Add remote setting to file, update TODO

This commit is contained in:
Michael DeHaan 2012-02-23 22:04:09 -05:00
parent 03647d64e9
commit 7eb2dd2dee
3 changed files with 29 additions and 19 deletions

View file

@ -1,10 +1,9 @@
TODO list and plans TODO list and plans
=================== ===================
* make remote user settable versus assuming remote login is named root
* modules for users, groups, and files, using puppet style ensure mechanics * modules for users, groups, and files, using puppet style ensure mechanics
* ansible-inventory -- gathering fact/hw info, storing in git, adding RSS * ansible-inventory - gathering fact/hw info, storing in git, adding RSS
* ansible-slurp ------ recursively rsync file trees for each host * ansible-slurp - recursively rsync file trees for each host
* very simple option constructing/parsing for modules * very simple option constructing/parsing for modules
* Dead-simple declarative configuration management engine using * Dead-simple declarative configuration management engine using
a runbook style recipe file, written in JSON or YAML a runbook style recipe file, written in JSON or YAML

View file

@ -32,6 +32,7 @@ DEFAULT_MODULE_NAME = 'ping'
DEFAULT_PATTERN = '*' DEFAULT_PATTERN = '*'
DEFAULT_FORKS = 3 DEFAULT_FORKS = 3
DEFAULT_MODULE_ARGS = '' DEFAULT_MODULE_ARGS = ''
DEFAULT_REMOTE_USER = 'root'
class Cli(object): class Cli(object):
@ -44,7 +45,7 @@ class Cli(object):
help="path to hosts list", default=DEFAULT_HOST_LIST) help="path to hosts list", default=DEFAULT_HOST_LIST)
parser.add_option("-L", "--library", dest="module_path", parser.add_option("-L", "--library", dest="module_path",
help="path to module library", default=DEFAULT_MODULE_PATH) help="path to module library", default=DEFAULT_MODULE_PATH)
parser.add_option("-F", "--forks", dest="forks", parser.add_option("-f", "--forks", dest="forks",
help="level of parallelism", default=DEFAULT_FORKS) help="level of parallelism", default=DEFAULT_FORKS)
parser.add_option("-n", "--name", dest="module_name", parser.add_option("-n", "--name", dest="module_name",
help="module name to execute", default=DEFAULT_MODULE_NAME) help="module name to execute", default=DEFAULT_MODULE_NAME)
@ -52,6 +53,8 @@ class Cli(object):
help="module arguments", default=DEFAULT_MODULE_ARGS) help="module arguments", default=DEFAULT_MODULE_ARGS)
parser.add_option("-p", "--pattern", dest="pattern", parser.add_option("-p", "--pattern", dest="pattern",
help="hostname pattern", default=DEFAULT_PATTERN) help="hostname pattern", default=DEFAULT_PATTERN)
parser.add_option("-u", "--remote-user", dest="remote_user",
help="remote username", default=DEFAULT_REMOTE_USER)
options, args = parser.parse_args() options, args = parser.parse_args()
@ -62,6 +65,7 @@ class Cli(object):
module_name=options.module_name, module_name=options.module_name,
module_path=options.module_path, module_path=options.module_path,
module_args=options.module_args.split(' '), module_args=options.module_args.split(' '),
remote_user=options.remote_user,
host_list=options.host_list, host_list=options.host_list,
forks=options.forks, forks=options.forks,
pattern=options.pattern, pattern=options.pattern,

View file

@ -36,6 +36,7 @@ DEFAULT_PATTERN = '*'
DEFAULT_FORKS = 3 DEFAULT_FORKS = 3
DEFAULT_MODULE_ARGS = '' DEFAULT_MODULE_ARGS = ''
DEFAULT_TIMEOUT = 60 DEFAULT_TIMEOUT = 60
DEFAULT_REMOTE_USER = 'root'
class Pooler(object): class Pooler(object):
@ -66,6 +67,7 @@ class Runner(object):
forks=DEFAULT_FORKS, forks=DEFAULT_FORKS,
timeout=DEFAULT_TIMEOUT, timeout=DEFAULT_TIMEOUT,
pattern=DEFAULT_PATTERN, pattern=DEFAULT_PATTERN,
remote_user=DEFAULT_REMOTE_USER,
verbose=False): verbose=False):
@ -81,6 +83,7 @@ class Runner(object):
self.module_args = module_args self.module_args = module_args
self.timeout = timeout self.timeout = timeout
self.verbose = verbose self.verbose = verbose
self.remote_user = remote_user
def _parse_hosts(self, host_list): def _parse_hosts(self, host_list):
''' parse the host inventory file if not sent as an array ''' ''' parse the host inventory file if not sent as an array '''
@ -103,23 +106,19 @@ class Runner(object):
ssh = paramiko.SSHClient() ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try: try:
ssh.connect(host, username='root', ssh.connect(host, username=self.remote_user,
allow_agent=True, look_for_keys=True) allow_agent=True, look_for_keys=True)
return ssh return [ True, ssh ]
except: except:
# TODO -- just convert traceback to string return [ False, traceback.format_exc() ]
# and return a seperate hash of failed hosts
if self.verbose:
traceback.print_exc()
return None
def _executor(self, host): def _executor(self, host):
''' callback executed in parallel for each host ''' ''' callback executed in parallel for each host '''
# TODO: try/catch returning none # TODO: try/catch returning none
conn = self._connect(host) ok, conn = self._connect(host)
if not conn: if not ok:
return [ host, None ] return [ host, False, conn ]
if self.module_name != "copy": if self.module_name != "copy":
# transfer a module, set it executable, and run it # transfer a module, set it executable, and run it
@ -127,15 +126,14 @@ class Runner(object):
self._exec_command(conn, "chmod +x %s" % outpath) self._exec_command(conn, "chmod +x %s" % outpath)
cmd = self._command(outpath) cmd = self._command(outpath)
result = self._exec_command(conn, cmd) result = self._exec_command(conn, cmd)
result = json.loads(result) return [ host, True, json.loads(result) ]
else: else:
# SFTP file copy module is not really a module # SFTP file copy module is not really a module
ftp = conn.open_sftp() ftp = conn.open_sftp()
ftp.put(self.module_args[0], self.module_args[1]) ftp.put(self.module_args[0], self.module_args[1])
ftp.close() ftp.close()
return [ host, 1 ] return [ host, True, 1 ]
return [ host, result ]
def _command(self, outpath): def _command(self, outpath):
''' form up a command string ''' ''' form up a command string '''
@ -168,8 +166,17 @@ class Runner(object):
def executor(x): def executor(x):
return self._executor(x) return self._executor(x)
results = Pooler.parmap(executor, hosts) results = Pooler.parmap(executor, hosts)
by_host = dict(results) results2 = {
return by_host "successful" : {},
"failed" : {}
}
for x in results:
(host, is_ok, result) = x
if not is_ok:
results2["failed"][host] = result
else:
results2["successful"][host] = result
return results2
if __name__ == '__main__': if __name__ == '__main__':