diff --git a/lib/ansible/runner/connection/__init__.py b/lib/ansible/runner/connection/__init__.py new file mode 100644 index 00000000000..da242a22fb3 --- /dev/null +++ b/lib/ansible/runner/connection/__init__.py @@ -0,0 +1,51 @@ +# (c) 2012, Michael DeHaan +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . +# + +################################################ + +import warnings +import traceback +import os +import time +import re +import shutil +import subprocess +import pipes +import socket +import random + +from ansible.runner.connection import local +from ansible.runner.connection import paramiko_ssh + +class Connection(object): + ''' Handles abstract connections to remote hosts ''' + + def __init__(self, runner, transport,sudo_user): + self.runner = runner + self.transport = transport + self.sudo_user = sudo_user + def connect(self, host, port=None): + conn = None + if self.transport == 'local': + conn = local.LocalConnection(self.runner, host) + elif self.transport == 'paramiko': + conn = paramiko_ssh.ParamikoConnection(self.runner, host, port) + if conn is None: + raise Exception("unsupported connection type") + return conn.connect() + diff --git a/lib/ansible/runner/connection/local.py b/lib/ansible/runner/connection/local.py new file mode 100644 index 00000000000..b1261185128 --- /dev/null +++ b/lib/ansible/runner/connection/local.py @@ -0,0 +1,81 @@ +# (c) 2012, Michael DeHaan +# +# This file is part of Ansible +# +# Ansible is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# Ansible is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Ansible. If not, see . +# + +################################################ + +import warnings +import traceback +import os +import time +import re +import shutil +import subprocess +import pipes +import socket +import random + +from ansible import errors + +class LocalConnection(object): + ''' Local based connections ''' + + def __init__(self, runner, host): + self.runner = runner + self.host = host + + def connect(self, port=None): + ''' connect to the local host; nothing to do here ''' + + return self + + def exec_command(self, cmd, tmp_path,sudo_user,sudoable=False): + ''' run a command on the local host ''' + if self.runner.sudo and sudoable: + cmd = "sudo -s %s" % cmd + if self.runner.sudo_pass: + # NOTE: if someone wants to add sudo w/ password to the local connection type, they are welcome + # to do so. The primary usage of the local connection is for crontab and kickstart usage however + # so this doesn't seem to be a huge priority + raise errors.AnsibleError("sudo with password is presently only supported on the paramiko (SSH) connection type") + + p = subprocess.Popen(cmd, shell=True, stdin=None, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = p.communicate() + return ("", stdout, stderr) + + def put_file(self, in_path, out_path): + ''' transfer a file from local to local ''' + if not os.path.exists(in_path): + raise errors.AnsibleFileNotFound("file or module does not exist: %s" % in_path) + try: + shutil.copyfile(in_path, out_path) + except shutil.Error: + traceback.print_exc() + raise errors.AnsibleError("failed to copy: %s and %s are the same" % (in_path, out_path)) + except IOError: + traceback.print_exc() + raise errors.AnsibleError("failed to transfer file to %s" % out_path) + + def fetch_file(self, in_path, out_path): + ''' fetch a file from local to local -- for copatibility ''' + self.put_file(in_path, out_path) + + def close(self): + ''' terminate the connection; nothing to do here ''' + + pass diff --git a/lib/ansible/runner/connection.py b/lib/ansible/runner/connection/paramiko_ssh.py similarity index 64% rename from lib/ansible/runner/connection.py rename to lib/ansible/runner/connection/paramiko_ssh.py index 63f59794e73..af3ea88a737 100644 --- a/lib/ansible/runner/connection.py +++ b/lib/ansible/runner/connection/paramiko_ssh.py @@ -36,32 +36,6 @@ with warnings.catch_warnings(): warnings.simplefilter("ignore") import paramiko - -################################################ - -class Connection(object): - ''' Handles abstract connections to remote hosts ''' - - def __init__(self, runner, transport,sudo_user): - self.runner = runner - self.transport = transport - self.sudo_user = sudo_user - def connect(self, host, port=None): - conn = None - if self.transport == 'local': - conn = LocalConnection(self.runner, host) - elif self.transport == 'paramiko': - conn = ParamikoConnection(self.runner, host, port) - if conn is None: - raise Exception("unsupported connection type") - return conn.connect() - -################################################ -# want to implement another connection type? -# follow duck-typing of ParamikoConnection -# you may wish to read config files in __init__ -# if you have any. Paramiko does not need any. - class ParamikoConnection(object): ''' SSH based connections with Paramiko ''' @@ -171,54 +145,3 @@ class ParamikoConnection(object): self.ssh.close() -############################################ -# add other connection types here - -class LocalConnection(object): - ''' Local based connections ''' - - def __init__(self, runner, host): - self.runner = runner - self.host = host - - def connect(self, port=None): - ''' connect to the local host; nothing to do here ''' - - return self - - def exec_command(self, cmd, tmp_path,sudo_user,sudoable=False): - ''' run a command on the local host ''' - if self.runner.sudo and sudoable: - cmd = "sudo -s %s" % cmd - if self.runner.sudo_pass: - # NOTE: if someone wants to add sudo w/ password to the local connection type, they are welcome - # to do so. The primary usage of the local connection is for crontab and kickstart usage however - # so this doesn't seem to be a huge priority - raise errors.AnsibleError("sudo with password is presently only supported on the paramiko (SSH) connection type") - - p = subprocess.Popen(cmd, shell=True, stdin=None, - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - stdout, stderr = p.communicate() - return ("", stdout, stderr) - - def put_file(self, in_path, out_path): - ''' transfer a file from local to local ''' - if not os.path.exists(in_path): - raise errors.AnsibleFileNotFound("file or module does not exist: %s" % in_path) - try: - shutil.copyfile(in_path, out_path) - except shutil.Error: - traceback.print_exc() - raise errors.AnsibleError("failed to copy: %s and %s are the same" % (in_path, out_path)) - except IOError: - traceback.print_exc() - raise errors.AnsibleError("failed to transfer file to %s" % out_path) - - def fetch_file(self, in_path, out_path): - ''' fetch a file from local to local -- for copatibility ''' - self.put_file(in_path, out_path) - - def close(self): - ''' terminate the connection; nothing to do here ''' - - pass diff --git a/setup.py b/setup.py index 1bdfe30d988..8665840c211 100644 --- a/setup.py +++ b/setup.py @@ -25,6 +25,7 @@ setup(name='ansible', 'ansible.inventory', 'ansible.playbook', 'ansible.runner', + 'ansible.runner.connection', ], scripts=[ 'bin/ansible',