Add remote setting to file, update TODO
This commit is contained in:
parent
03647d64e9
commit
7eb2dd2dee
3 changed files with 29 additions and 19 deletions
5
TODO.md
5
TODO.md
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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__':
|
||||||
|
|
Loading…
Reference in a new issue