Misc refactoring, updated TODO to reflect new templating features being completed
This commit is contained in:
parent
ba9468266f
commit
de80166b6d
2 changed files with 51 additions and 52 deletions
20
TODO.md
20
TODO.md
|
@ -4,30 +4,22 @@ TODO list and plans
|
||||||
Playbook TODO:
|
Playbook TODO:
|
||||||
|
|
||||||
* error codes and failure summaries
|
* error codes and failure summaries
|
||||||
* create modules that return 'changed' attributes
|
* handle 'changed' attributes
|
||||||
* fail nodes on errors, i.e. remove from host list, rather than continuing to pound them
|
* fail nodes on errors, i.e. remove from host list, rather than continuing to pound them
|
||||||
* further improve output
|
* further improve output
|
||||||
* more conditional capability
|
* more conditional capability (if statement) (?)
|
||||||
* very good logging
|
* very good logging
|
||||||
|
|
||||||
Command module:
|
Command module:
|
||||||
* allow additional key/value options to be passed to any module (via ENV vars?)
|
* magic to pull async & timeout options off of the command line and not feed them
|
||||||
* allow this to be expressed in playbook as a 4th option after the array options list
|
to the app we're executing
|
||||||
* use this to pass timeout and async params to the command module
|
|
||||||
default timeouts will be infinite, async False
|
|
||||||
|
|
||||||
General:
|
General:
|
||||||
|
|
||||||
* logging
|
* better logging
|
||||||
* async options
|
* async options
|
||||||
* modules for users, groups, and files, using puppet style ensure mechanics
|
* modules for users, groups, and files, using puppet style ensure mechanics
|
||||||
* very simple option constructing/parsing for modules
|
* think about how to build idempotency (aka Puppet-style 'creates') around command module?
|
||||||
* templating module (how might this work syntax wise?) with facter/ohai awareness
|
|
||||||
* probably could lay down a values.json file
|
|
||||||
* use copy capabilities to move files to tmp, run python templating
|
|
||||||
* maybe support templating engine of choice
|
|
||||||
* think about how to build idempotency guards around command module?
|
|
||||||
* think about how to feed extra JSON data onto system
|
|
||||||
|
|
||||||
Bonus utilities:
|
Bonus utilities:
|
||||||
|
|
||||||
|
|
|
@ -24,11 +24,8 @@ import multiprocessing
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
import traceback
|
import traceback
|
||||||
|
import paramiko # non-core dependency
|
||||||
# non-core
|
import ansible.constants as C
|
||||||
import paramiko
|
|
||||||
|
|
||||||
import constants as C
|
|
||||||
|
|
||||||
def _executor_hook(x):
|
def _executor_hook(x):
|
||||||
''' callback used by multiprocessing pool '''
|
''' callback used by multiprocessing pool '''
|
||||||
|
@ -49,9 +46,16 @@ class Runner(object):
|
||||||
remote_pass=C.DEFAULT_REMOTE_PASS,
|
remote_pass=C.DEFAULT_REMOTE_PASS,
|
||||||
verbose=False):
|
verbose=False):
|
||||||
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Constructor.
|
Constructor
|
||||||
|
host_list -- file on disk listing hosts to manage, or an array of hostnames
|
||||||
|
pattern ------ a fnmatch pattern selecting some of the hosts in host_list
|
||||||
|
module_path -- location of ansible library on disk
|
||||||
|
module_name -- which module to run
|
||||||
|
module_args -- arguments to pass to module
|
||||||
|
forks -------- how parallel should we be? 1 is extra debuggable.
|
||||||
|
remote_user -- who to login as (default root)
|
||||||
|
remote_pass -- provide only if you don't want to use keys or ssh-agent
|
||||||
'''
|
'''
|
||||||
|
|
||||||
self.host_list = self._parse_hosts(host_list)
|
self.host_list = self._parse_hosts(host_list)
|
||||||
|
@ -109,44 +113,52 @@ class Runner(object):
|
||||||
for filename in files:
|
for filename in files:
|
||||||
self._exec_command(conn, "rm -f %s" % filename)
|
self._exec_command(conn, "rm -f %s" % filename)
|
||||||
|
|
||||||
|
def _transfer_file(self, conn, source, dest):
|
||||||
|
self.remote_log(conn, 'COPY remote:%s local:%s' % (source, dest))
|
||||||
|
ftp = conn.open_sftp()
|
||||||
|
ftp.put(source, dest)
|
||||||
|
ftp.close()
|
||||||
|
|
||||||
|
def _transfer_module(self, conn):
|
||||||
|
outpath = self._copy_module(conn)
|
||||||
|
self._exec_command(conn, "chmod +x %s" % outpath)
|
||||||
|
return outpath
|
||||||
|
|
||||||
|
def _execute_module(self, conn, outpath):
|
||||||
|
cmd = self._command(outpath)
|
||||||
|
result = self._exec_command(conn, cmd)
|
||||||
|
self._delete_remote_files(conn, [ outpath ])
|
||||||
|
return result
|
||||||
|
|
||||||
def _execute_normal_module(self, conn, host):
|
def _execute_normal_module(self, conn, host):
|
||||||
''' transfer a module, set it executable, and run it '''
|
''' transfer a module, set it executable, and run it '''
|
||||||
|
|
||||||
outpath = self._copy_module(conn)
|
module = self._transfer_module(conn)
|
||||||
self._exec_command(conn, "chmod +x %s" % outpath)
|
result = self._execute_module(conn, module)
|
||||||
cmd = self._command(outpath)
|
|
||||||
result = self._exec_command(conn, cmd)
|
|
||||||
self._delete_remote_files(conn, outpath)
|
|
||||||
return self._return_from_module(conn, host, result)
|
return self._return_from_module(conn, host, result)
|
||||||
|
|
||||||
def _execute_copy(self, conn, host):
|
def _execute_copy(self, conn, host):
|
||||||
''' transfer a file + copy module, run copy module, clean up '''
|
''' handler for file transfer operations '''
|
||||||
|
|
||||||
self.remote_log(conn, 'COPY remote:%s local:%s' % (self.module_args[0], self.module_args[1]))
|
# transfer the file to a remote tmp location
|
||||||
source = self.module_args[0]
|
source = self.module_args[0]
|
||||||
dest = self.module_args[1]
|
dest = self.module_args[1]
|
||||||
tmp_dest = self._get_tmp_path(conn, dest.split("/")[-1])
|
tmp_dest = self._get_tmp_path(conn, dest.split("/")[-1])
|
||||||
|
self._transfer_file(conn, source, tmp_dest)
|
||||||
ftp = conn.open_sftp()
|
|
||||||
ftp.put(source, tmp_dest)
|
|
||||||
ftp.close()
|
|
||||||
|
|
||||||
# install the copy module
|
# install the copy module
|
||||||
|
|
||||||
self.module_name = 'copy'
|
self.module_name = 'copy'
|
||||||
outpath = self._copy_module(conn)
|
module = self._transfer_module(conn)
|
||||||
self._exec_command(conn, "chmod +x %s" % outpath)
|
|
||||||
|
|
||||||
# run the copy module
|
# run the copy module
|
||||||
|
|
||||||
self.module_args = [ tmp_dest, dest ]
|
self.module_args = [ tmp_dest, dest ]
|
||||||
cmd = self._command(outpath)
|
result = self._execute_module(conn, module)
|
||||||
result = self._exec_command(conn, cmd)
|
self._delete_remote_files(conn, tmp_dest)
|
||||||
self._delete_remote_files(conn, [outpath, tmp_dest])
|
|
||||||
|
|
||||||
return self._return_from_module(conn, host, result)
|
return self._return_from_module(conn, host, result)
|
||||||
|
|
||||||
def _execute_template(self, conn, host):
|
def _execute_template(self, conn, host):
|
||||||
|
''' handler for template operations '''
|
||||||
|
|
||||||
source = self.module_args[0]
|
source = self.module_args[0]
|
||||||
dest = self.module_args[1]
|
dest = self.module_args[1]
|
||||||
metadata = '/etc/ansible/setup'
|
metadata = '/etc/ansible/setup'
|
||||||
|
@ -154,21 +166,16 @@ class Runner(object):
|
||||||
# first copy the source template over
|
# first copy the source template over
|
||||||
tempname = os.path.split(source)[-1]
|
tempname = os.path.split(source)[-1]
|
||||||
temppath = self._get_tmp_path(conn, tempname)
|
temppath = self._get_tmp_path(conn, tempname)
|
||||||
self.remote_log(conn, 'COPY remote:%s local:%s' % (source, temppath))
|
self._transfer_file(conn, source, temppath)
|
||||||
ftp = conn.open_sftp()
|
|
||||||
ftp.put(source, temppath)
|
|
||||||
ftp.close()
|
|
||||||
|
|
||||||
# install the template module
|
# install the template module
|
||||||
self.module_name = 'template'
|
self.module_name = 'template'
|
||||||
outpath = self._copy_module(conn)
|
module = self._transfer_module(conn)
|
||||||
self._exec_command(conn, "chmod +x %s" % outpath)
|
|
||||||
|
|
||||||
# run the template module
|
# run the template module
|
||||||
self.module_args = [ temppath, dest, metadata ]
|
self.module_args = [ temppath, dest, metadata ]
|
||||||
result = self._exec_command(conn, self._command(outpath))
|
result = self._execute_module(conn, module)
|
||||||
# clean up
|
self._delete_remote_files(conn, [ temppath ])
|
||||||
self._delete_remote_files(conn, [ outpath, temppath ])
|
|
||||||
return self._return_from_module(conn, host, result)
|
return self._return_from_module(conn, host, result)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue