From b8f138cabb26fb587df0333d054bf1917d80735d Mon Sep 17 00:00:00 2001 From: Peter Sprygada Date: Sun, 12 Feb 2017 07:52:50 -0500 Subject: [PATCH] adds connection module to module_utils (#21310) * connection module connecting to persistent sockets --- lib/ansible/module_utils/connection.py | 75 ++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 lib/ansible/module_utils/connection.py diff --git a/lib/ansible/module_utils/connection.py b/lib/ansible/module_utils/connection.py new file mode 100644 index 00000000000..8848e67db3a --- /dev/null +++ b/lib/ansible/module_utils/connection.py @@ -0,0 +1,75 @@ +# +# This code is part of Ansible, but is an independent component. +# This particular file snippet, and this file snippet only, is BSD licensed. +# Modules you write using this snippet, which is embedded dynamically by Ansible +# still belong to the author of the module, and may assign their own license +# to the complete work. +# +# (c) 2017 Red Hat Inc. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +import socket +import struct +import signal + +from ansible.module_utils.basic import get_exception +from ansible.module_utils._text import to_bytes, to_native + +def send_data(s, data): + packed_len = struct.pack('!Q',len(data)) + return s.sendall(packed_len + data) + +def recv_data(s): + header_len = 8 # size of a packed unsigned long long + data = to_bytes("") + while len(data) < header_len: + d = s.recv(header_len - len(data)) + if not d: + return None + data += d + data_len = struct.unpack('!Q',data[:header_len])[0] + data = data[header_len:] + while len(data) < data_len: + d = s.recv(data_len - len(data)) + if not d: + return None + data += d + return data + +def exec_command(module, command): + try: + sf = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + sf.connect(module._socket_path) + + data = "EXEC: %s" % command + send_data(sf, to_bytes(data.strip())) + + rc = int(recv_data(sf), 10) + stdout = recv_data(sf) + stderr = recv_data(sf) + except socket.error: + exc = get_exception() + sf.close() + module.fail_json(msg='unable to connect to socket', err=str(exc)) + + sf.close() + + return (rc, to_native(stdout), to_native(stderr))