mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Pull persistent connection parameters via get_option (#39367)
* WIP Pull persistent connection parameters via get_option * Fix pep8 * Add use_persistent_connection setting to paramiko_ssh plugin * Add vars section to persistent_command_timeout setting and prevail provider values over config manager * Use persistent_command_timeout on network_cli instead of timeout * Fix unit tests If we don't call loader to get network_cli, then _load_name is never set and we get KeyError. * Pull persistent_command_timeout via config manager for ios connection local * Pull persistent_command_timeout via config manager on connection local
This commit is contained in:
parent
865f2c5990
commit
62e1c14edc
12 changed files with 64 additions and 22 deletions
|
@ -107,7 +107,7 @@ class ConnectionProcess(object):
|
||||||
while self.connection.connected:
|
while self.connection.connected:
|
||||||
signal.signal(signal.SIGALRM, self.connect_timeout)
|
signal.signal(signal.SIGALRM, self.connect_timeout)
|
||||||
signal.signal(signal.SIGTERM, self.handler)
|
signal.signal(signal.SIGTERM, self.handler)
|
||||||
signal.alarm(C.PERSISTENT_CONNECT_TIMEOUT)
|
signal.alarm(self.connection.get_option('persistent_connect_timeout'))
|
||||||
|
|
||||||
self.exception = None
|
self.exception = None
|
||||||
(s, addr) = self.sock.accept()
|
(s, addr) = self.sock.accept()
|
||||||
|
@ -141,7 +141,8 @@ class ConnectionProcess(object):
|
||||||
self.shutdown()
|
self.shutdown()
|
||||||
|
|
||||||
def connect_timeout(self, signum, frame):
|
def connect_timeout(self, signum, frame):
|
||||||
display.display('persistent connection idle timeout triggered, timeout value is %s secs' % C.PERSISTENT_CONNECT_TIMEOUT, log_only=True)
|
display.display('persistent connection idle timeout triggered, timeout value is %s secs'
|
||||||
|
% self.connection.get_option('persistent_connect_timeout'), log_only=True)
|
||||||
self.shutdown()
|
self.shutdown()
|
||||||
|
|
||||||
def command_timeout(self, signum, frame):
|
def command_timeout(self, signum, frame):
|
||||||
|
|
|
@ -810,7 +810,7 @@ class TaskExecutor:
|
||||||
self._play_context.set_options_from_plugin(connection)
|
self._play_context.set_options_from_plugin(connection)
|
||||||
|
|
||||||
if any(((connection.supports_persistence and C.USE_PERSISTENT_CONNECTIONS), connection.force_persistence)):
|
if any(((connection.supports_persistence and C.USE_PERSISTENT_CONNECTIONS), connection.force_persistence)):
|
||||||
self._play_context.timeout = C.PERSISTENT_COMMAND_TIMEOUT
|
self._play_context.timeout = connection.get_option('persistent_command_timeout')
|
||||||
display.vvvv('attempting to start connection', host=self._play_context.remote_addr)
|
display.vvvv('attempting to start connection', host=self._play_context.remote_addr)
|
||||||
display.vvvv('using connection plugin %s' % connection.transport, host=self._play_context.remote_addr)
|
display.vvvv('using connection plugin %s' % connection.transport, host=self._play_context.remote_addr)
|
||||||
socket_path = self._start_connection()
|
socket_path = self._start_connection()
|
||||||
|
|
|
@ -66,7 +66,7 @@ class ActionModule(_ActionModule):
|
||||||
pc.remote_user = provider['username'] or self._play_context.connection_user
|
pc.remote_user = provider['username'] or self._play_context.connection_user
|
||||||
pc.password = provider['password'] or self._play_context.password
|
pc.password = provider['password'] or self._play_context.password
|
||||||
pc.private_key_file = provider['ssh_keyfile'] or self._play_context.private_key_file
|
pc.private_key_file = provider['ssh_keyfile'] or self._play_context.private_key_file
|
||||||
pc.timeout = int(provider['timeout'] or C.PERSISTENT_COMMAND_TIMEOUT)
|
pc.timeout = int(provider['timeout']) if provider['timeout'] else None
|
||||||
pc.become = provider['authorize'] or False
|
pc.become = provider['authorize'] or False
|
||||||
if pc.become:
|
if pc.become:
|
||||||
pc.become_method = 'enable'
|
pc.become_method = 'enable'
|
||||||
|
@ -75,6 +75,9 @@ class ActionModule(_ActionModule):
|
||||||
display.vvv('using connection plugin %s (was local)' % pc.connection, pc.remote_addr)
|
display.vvv('using connection plugin %s (was local)' % pc.connection, pc.remote_addr)
|
||||||
connection = self._shared_loader_obj.connection_loader.get('persistent', pc, sys.stdin)
|
connection = self._shared_loader_obj.connection_loader.get('persistent', pc, sys.stdin)
|
||||||
|
|
||||||
|
if connection._play_context.timeout is None:
|
||||||
|
connection._play_context.timeout = connection.get_option('persistent_command_timeout')
|
||||||
|
|
||||||
socket_path = connection.run()
|
socket_path = connection.run()
|
||||||
display.vvvv('socket_path: %s' % socket_path, pc.remote_addr)
|
display.vvvv('socket_path: %s' % socket_path, pc.remote_addr)
|
||||||
if not socket_path:
|
if not socket_path:
|
||||||
|
|
|
@ -58,7 +58,7 @@ class ActionModule(_ActionModule):
|
||||||
pc.remote_user = provider['username'] or self._play_context.connection_user
|
pc.remote_user = provider['username'] or self._play_context.connection_user
|
||||||
pc.password = provider['password'] or self._play_context.password
|
pc.password = provider['password'] or self._play_context.password
|
||||||
pc.private_key_file = provider['ssh_keyfile'] or self._play_context.private_key_file
|
pc.private_key_file = provider['ssh_keyfile'] or self._play_context.private_key_file
|
||||||
pc.timeout = int(provider['timeout'] or C.PERSISTENT_COMMAND_TIMEOUT)
|
pc.timeout = int(provider['timeout']) if provider['timeout'] else None
|
||||||
pc.become = provider['authorize'] or False
|
pc.become = provider['authorize'] or False
|
||||||
if pc.become:
|
if pc.become:
|
||||||
pc.become_method = 'enable'
|
pc.become_method = 'enable'
|
||||||
|
@ -67,6 +67,9 @@ class ActionModule(_ActionModule):
|
||||||
display.vvv('using connection plugin %s (was local)' % pc.connection, pc.remote_addr)
|
display.vvv('using connection plugin %s (was local)' % pc.connection, pc.remote_addr)
|
||||||
connection = self._shared_loader_obj.connection_loader.get('persistent', pc, sys.stdin)
|
connection = self._shared_loader_obj.connection_loader.get('persistent', pc, sys.stdin)
|
||||||
|
|
||||||
|
if connection._play_context.timeout is None:
|
||||||
|
connection._play_context.timeout = connection.get_option('persistent_command_timeout')
|
||||||
|
|
||||||
socket_path = connection.run()
|
socket_path = connection.run()
|
||||||
display.vvvv('socket_path: %s' % socket_path, pc.remote_addr)
|
display.vvvv('socket_path: %s' % socket_path, pc.remote_addr)
|
||||||
if not socket_path:
|
if not socket_path:
|
||||||
|
|
|
@ -61,11 +61,14 @@ class ActionModule(_ActionModule):
|
||||||
pc.port = int(provider['port'] or self._play_context.port or 22)
|
pc.port = int(provider['port'] or self._play_context.port or 22)
|
||||||
pc.remote_user = provider['username'] or self._play_context.connection_user
|
pc.remote_user = provider['username'] or self._play_context.connection_user
|
||||||
pc.password = provider['password'] or self._play_context.password
|
pc.password = provider['password'] or self._play_context.password
|
||||||
pc.timeout = int(provider['timeout'] or C.PERSISTENT_COMMAND_TIMEOUT)
|
pc.timeout = int(provider['timeout']) if provider['timeout'] else None
|
||||||
|
|
||||||
display.vvv('using connection plugin %s (was local)' % pc.connection, pc.remote_addr)
|
display.vvv('using connection plugin %s (was local)' % pc.connection, pc.remote_addr)
|
||||||
connection = self._shared_loader_obj.connection_loader.get('persistent', pc, sys.stdin)
|
connection = self._shared_loader_obj.connection_loader.get('persistent', pc, sys.stdin)
|
||||||
|
|
||||||
|
if connection._play_context.timeout is None:
|
||||||
|
connection._play_context.timeout = connection.get_option('persistent_command_timeout')
|
||||||
|
|
||||||
socket_path = connection.run()
|
socket_path = connection.run()
|
||||||
display.vvvv('socket_path: %s' % socket_path, pc.remote_addr)
|
display.vvvv('socket_path: %s' % socket_path, pc.remote_addr)
|
||||||
if not socket_path:
|
if not socket_path:
|
||||||
|
|
|
@ -72,11 +72,14 @@ class ActionModule(_ActionModule):
|
||||||
pc.remote_user = provider['username'] or self._play_context.connection_user
|
pc.remote_user = provider['username'] or self._play_context.connection_user
|
||||||
pc.password = provider['password'] or self._play_context.password
|
pc.password = provider['password'] or self._play_context.password
|
||||||
pc.private_key_file = provider['ssh_keyfile'] or self._play_context.private_key_file
|
pc.private_key_file = provider['ssh_keyfile'] or self._play_context.private_key_file
|
||||||
pc.timeout = int(provider['timeout'] or C.PERSISTENT_COMMAND_TIMEOUT)
|
pc.timeout = int(provider['timeout']) if provider['timeout'] else None
|
||||||
|
|
||||||
display.vvv('using connection plugin %s (was local)' % pc.connection, pc.remote_addr)
|
display.vvv('using connection plugin %s (was local)' % pc.connection, pc.remote_addr)
|
||||||
connection = self._shared_loader_obj.connection_loader.get('persistent', pc, sys.stdin)
|
connection = self._shared_loader_obj.connection_loader.get('persistent', pc, sys.stdin)
|
||||||
|
|
||||||
|
if connection._play_context.timeout is None:
|
||||||
|
connection._play_context.timeout = connection.get_option('persistent_command_timeout')
|
||||||
|
|
||||||
socket_path = connection.run()
|
socket_path = connection.run()
|
||||||
display.vvvv('socket_path: %s' % socket_path, pc.remote_addr)
|
display.vvvv('socket_path: %s' % socket_path, pc.remote_addr)
|
||||||
if not socket_path:
|
if not socket_path:
|
||||||
|
|
|
@ -69,7 +69,7 @@ class ActionModule(_ActionModule):
|
||||||
pc.remote_user = provider['username'] or self._play_context.connection_user
|
pc.remote_user = provider['username'] or self._play_context.connection_user
|
||||||
pc.password = provider['password'] or self._play_context.password
|
pc.password = provider['password'] or self._play_context.password
|
||||||
pc.private_key_file = provider['ssh_keyfile'] or self._play_context.private_key_file
|
pc.private_key_file = provider['ssh_keyfile'] or self._play_context.private_key_file
|
||||||
pc.timeout = int(provider['timeout'] or C.PERSISTENT_COMMAND_TIMEOUT)
|
pc.timeout = int(provider['timeout']) if provider['timeout'] else None
|
||||||
pc.become = provider['authorize'] or False
|
pc.become = provider['authorize'] or False
|
||||||
if pc.become:
|
if pc.become:
|
||||||
pc.become_method = 'enable'
|
pc.become_method = 'enable'
|
||||||
|
@ -78,6 +78,9 @@ class ActionModule(_ActionModule):
|
||||||
display.vvv('using connection plugin %s (was local)' % pc.connection, pc.remote_addr)
|
display.vvv('using connection plugin %s (was local)' % pc.connection, pc.remote_addr)
|
||||||
connection = self._shared_loader_obj.connection_loader.get('persistent', pc, sys.stdin)
|
connection = self._shared_loader_obj.connection_loader.get('persistent', pc, sys.stdin)
|
||||||
|
|
||||||
|
if connection._play_context.timeout is None:
|
||||||
|
connection._play_context.timeout = connection.get_option('persistent_command_timeout')
|
||||||
|
|
||||||
socket_path = connection.run()
|
socket_path = connection.run()
|
||||||
display.vvvv('socket_path: %s' % socket_path, pc.remote_addr)
|
display.vvvv('socket_path: %s' % socket_path, pc.remote_addr)
|
||||||
if not socket_path:
|
if not socket_path:
|
||||||
|
|
|
@ -58,11 +58,14 @@ class ActionModule(_ActionModule):
|
||||||
pc.remote_user = provider['username'] or self._play_context.connection_user
|
pc.remote_user = provider['username'] or self._play_context.connection_user
|
||||||
pc.password = provider['password'] or self._play_context.password
|
pc.password = provider['password'] or self._play_context.password
|
||||||
pc.private_key_file = provider['ssh_keyfile'] or self._play_context.private_key_file
|
pc.private_key_file = provider['ssh_keyfile'] or self._play_context.private_key_file
|
||||||
pc.timeout = int(provider['timeout'] or C.PERSISTENT_COMMAND_TIMEOUT)
|
pc.timeout = int(provider['timeout']) if provider['timeout'] else None
|
||||||
|
|
||||||
display.vvv('using connection plugin %s (was local)' % pc.connection, pc.remote_addr)
|
display.vvv('using connection plugin %s (was local)' % pc.connection, pc.remote_addr)
|
||||||
connection = self._shared_loader_obj.connection_loader.get('persistent', pc, sys.stdin)
|
connection = self._shared_loader_obj.connection_loader.get('persistent', pc, sys.stdin)
|
||||||
|
|
||||||
|
if connection._play_context.timeout is None:
|
||||||
|
connection._play_context.timeout = connection.get_option('persistent_command_timeout')
|
||||||
|
|
||||||
socket_path = connection.run()
|
socket_path = connection.run()
|
||||||
display.vvvv('socket_path: %s' % socket_path, pc.remote_addr)
|
display.vvvv('socket_path: %s' % socket_path, pc.remote_addr)
|
||||||
if not socket_path:
|
if not socket_path:
|
||||||
|
|
|
@ -151,8 +151,8 @@ options:
|
||||||
close
|
close
|
||||||
default: 10
|
default: 10
|
||||||
ini:
|
ini:
|
||||||
section: persistent_connection
|
- section: persistent_connection
|
||||||
key: persistent_command_timeout
|
key: command_timeout
|
||||||
env:
|
env:
|
||||||
- name: ANSIBLE_PERSISTENT_COMMAND_TIMEOUT
|
- name: ANSIBLE_PERSISTENT_COMMAND_TIMEOUT
|
||||||
"""
|
"""
|
||||||
|
@ -298,7 +298,7 @@ class Connection(ConnectionBase):
|
||||||
display.vvvv('ssh connection done, setting terminal', host=self._play_context.remote_addr)
|
display.vvvv('ssh connection done, setting terminal', host=self._play_context.remote_addr)
|
||||||
|
|
||||||
self._ssh_shell = ssh.ssh.invoke_shell()
|
self._ssh_shell = ssh.ssh.invoke_shell()
|
||||||
self._ssh_shell.settimeout(self._play_context.timeout)
|
self._ssh_shell.settimeout(self.get_option('persistent_command_timeout'))
|
||||||
|
|
||||||
network_os = self._play_context.network_os
|
network_os = self._play_context.network_os
|
||||||
if not network_os:
|
if not network_os:
|
||||||
|
|
|
@ -114,8 +114,16 @@ DOCUMENTATION = """
|
||||||
version_added: '2.5'
|
version_added: '2.5'
|
||||||
- name: ansible_paramiko_host_key_checking
|
- name: ansible_paramiko_host_key_checking
|
||||||
version_added: '2.5'
|
version_added: '2.5'
|
||||||
|
use_persistent_connections:
|
||||||
|
description: 'Toggles the use of persistence for connections'
|
||||||
|
type: boolean
|
||||||
|
default: False
|
||||||
|
env:
|
||||||
|
- name: ANSIBLE_USE_PERSISTENT_CONNECTIONS
|
||||||
|
ini:
|
||||||
|
- section: defaults
|
||||||
|
key: use_persistent_connections
|
||||||
# TODO:
|
# TODO:
|
||||||
#C.USE_PERSISTENT_CONNECTIONS:
|
|
||||||
#timeout=self._play_context.timeout,
|
#timeout=self._play_context.timeout,
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
@ -188,7 +196,7 @@ class MyAddPolicy(object):
|
||||||
fingerprint = hexlify(key.get_fingerprint())
|
fingerprint = hexlify(key.get_fingerprint())
|
||||||
ktype = key.get_name()
|
ktype = key.get_name()
|
||||||
|
|
||||||
if C.USE_PERSISTENT_CONNECTIONS or self.connection.force_persistence:
|
if self.connection.get_option('use_persistent_connections') or self.connection.force_persistence:
|
||||||
# don't print the prompt string since the user cannot respond
|
# don't print the prompt string since the user cannot respond
|
||||||
# to the question anyway
|
# to the question anyway
|
||||||
raise AnsibleError(AUTHENTICITY_MSG[1:92] % (hostname, ktype, fingerprint))
|
raise AnsibleError(AUTHENTICITY_MSG[1:92] % (hostname, ktype, fingerprint))
|
||||||
|
|
|
@ -6,12 +6,26 @@ from __future__ import (absolute_import, division, print_function)
|
||||||
__metaclass__ = type
|
__metaclass__ = type
|
||||||
|
|
||||||
DOCUMENTATION = """
|
DOCUMENTATION = """
|
||||||
author: Ansible Core Team
|
author: Ansible Core Team
|
||||||
connection: persistent
|
connection: persistent
|
||||||
short_description: Use a persistent unix socket for connection
|
short_description: Use a persistent unix socket for connection
|
||||||
description:
|
description:
|
||||||
- This is a helper plugin to allow making other connections persistent.
|
- This is a helper plugin to allow making other connections persistent.
|
||||||
version_added: "2.3"
|
version_added: "2.3"
|
||||||
|
options:
|
||||||
|
persistent_command_timeout:
|
||||||
|
type: int
|
||||||
|
description:
|
||||||
|
- Configures, in seconds, the amount of time to wait for a command to
|
||||||
|
return from the remote device. If this timer is exceeded before the
|
||||||
|
command returns, the connection plugin will raise an exception and
|
||||||
|
close
|
||||||
|
default: 10
|
||||||
|
ini:
|
||||||
|
- section: persistent_connection
|
||||||
|
key: command_timeout
|
||||||
|
env:
|
||||||
|
- name: ANSIBLE_PERSISTENT_COMMAND_TIMEOUT
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import pty
|
import pty
|
||||||
|
|
|
@ -31,6 +31,7 @@ from ansible.compat.tests.mock import patch, MagicMock
|
||||||
from ansible.errors import AnsibleConnectionFailure
|
from ansible.errors import AnsibleConnectionFailure
|
||||||
from ansible.playbook.play_context import PlayContext
|
from ansible.playbook.play_context import PlayContext
|
||||||
from ansible.plugins.connection import network_cli
|
from ansible.plugins.connection import network_cli
|
||||||
|
from ansible.plugins.loader import connection_loader
|
||||||
|
|
||||||
|
|
||||||
class TestConnectionClass(unittest.TestCase):
|
class TestConnectionClass(unittest.TestCase):
|
||||||
|
@ -40,7 +41,7 @@ class TestConnectionClass(unittest.TestCase):
|
||||||
pc = PlayContext()
|
pc = PlayContext()
|
||||||
new_stdin = StringIO()
|
new_stdin = StringIO()
|
||||||
|
|
||||||
conn = network_cli.Connection(pc, new_stdin)
|
conn = connection_loader.get('network_cli', pc, '/dev/null')
|
||||||
conn.ssh = MagicMock()
|
conn.ssh = MagicMock()
|
||||||
conn.receive = MagicMock()
|
conn.receive = MagicMock()
|
||||||
conn._terminal = MagicMock()
|
conn._terminal = MagicMock()
|
||||||
|
@ -52,7 +53,7 @@ class TestConnectionClass(unittest.TestCase):
|
||||||
pc = PlayContext()
|
pc = PlayContext()
|
||||||
new_stdin = StringIO()
|
new_stdin = StringIO()
|
||||||
|
|
||||||
conn = network_cli.Connection(pc, new_stdin)
|
conn = connection_loader.get('network_cli', pc, '/dev/null')
|
||||||
conn.ssh = MagicMock()
|
conn.ssh = MagicMock()
|
||||||
conn.receive = MagicMock()
|
conn.receive = MagicMock()
|
||||||
conn._terminal = MagicMock()
|
conn._terminal = MagicMock()
|
||||||
|
@ -65,7 +66,7 @@ class TestConnectionClass(unittest.TestCase):
|
||||||
pc = PlayContext()
|
pc = PlayContext()
|
||||||
new_stdin = StringIO()
|
new_stdin = StringIO()
|
||||||
|
|
||||||
conn = network_cli.Connection(pc, new_stdin)
|
conn = connection_loader.get('network_cli', pc, '/dev/null')
|
||||||
pc.network_os = 'ios'
|
pc.network_os = 'ios'
|
||||||
|
|
||||||
conn.ssh = MagicMock()
|
conn.ssh = MagicMock()
|
||||||
|
|
Loading…
Reference in a new issue