Collated PEP8 fixes (#25293)

- Make PEP8 compliant
This commit is contained in:
Dag Wieers
2017-06-02 13:14:11 +02:00
committed by John R Barker
parent 2f33c1a1a1
commit 5553b20828
206 changed files with 1853 additions and 1870 deletions

View File

@@ -62,11 +62,11 @@ class PluginLoader:
def __init__(self, class_name, package, config, subdir, aliases={}, required_base_class=None):
self.class_name = class_name
self.base_class = required_base_class
self.package = package
self.subdir = subdir
self.aliases = aliases
self.class_name = class_name
self.base_class = required_base_class
self.package = package
self.subdir = subdir
self.aliases = aliases
if config and not isinstance(config, list):
config = [config]
@@ -82,8 +82,8 @@ class PluginLoader:
if class_name not in PLUGIN_PATH_CACHE:
PLUGIN_PATH_CACHE[class_name] = defaultdict(dict)
self._module_cache = MODULE_CACHE[class_name]
self._paths = PATH_CACHE[class_name]
self._module_cache = MODULE_CACHE[class_name]
self._paths = PATH_CACHE[class_name]
self._plugin_path_cache = PLUGIN_PATH_CACHE[class_name]
self._extra_dirs = []
@@ -95,10 +95,10 @@ class PluginLoader:
'''
class_name = data.get('class_name')
package = data.get('package')
config = data.get('config')
subdir = data.get('subdir')
aliases = data.get('aliases')
package = data.get('package')
config = data.get('config')
subdir = data.get('subdir')
aliases = data.get('aliases')
base_class = data.get('base_class')
PATH_CACHE[class_name] = data.get('PATH_CACHE')
@@ -114,16 +114,16 @@ class PluginLoader:
'''
return dict(
class_name = self.class_name,
base_class = self.base_class,
package = self.package,
config = self.config,
subdir = self.subdir,
aliases = self.aliases,
_extra_dirs = self._extra_dirs,
_searched_paths = self._searched_paths,
PATH_CACHE = PATH_CACHE[self.class_name],
PLUGIN_PATH_CACHE = PLUGIN_PATH_CACHE[self.class_name],
class_name=self.class_name,
base_class=self.base_class,
package=self.package,
config=self.config,
subdir=self.subdir,
aliases=self.aliases,
_extra_dirs=self._extra_dirs,
_searched_paths=self._searched_paths,
PATH_CACHE=PATH_CACHE[self.class_name],
PLUGIN_PATH_CACHE=PLUGIN_PATH_CACHE[self.class_name],
)
def format_paths(self, paths):
@@ -145,7 +145,7 @@ class PluginLoader:
for root, subdirs, files in os.walk(dir, followlinks=True):
if '__init__.py' in files:
for x in subdirs:
results.append(os.path.join(root,x))
results.append(os.path.join(root, x))
return results
def _get_package_paths(self, subdirs=True):
@@ -271,7 +271,7 @@ class PluginLoader:
# HACK: We have no way of executing python byte
# compiled files as ansible modules so specifically exclude them
### FIXME: I believe this is only correct for modules and
# FIXME: I believe this is only correct for modules and
# module_utils. For all other plugins we want .pyc and .pyo should
# bew valid
if full_path.endswith(('.pyc', '.pyo')):
@@ -313,10 +313,10 @@ class PluginLoader:
if alias_name in pull_cache:
if not ignore_deprecated and not os.path.islink(pull_cache[alias_name]):
display.deprecated('%s is kept for backwards compatibility '
'but usage is discouraged. The module '
'documentation details page may explain '
'more about this rationale.' %
name.lstrip('_'))
'but usage is discouraged. The module '
'documentation details page may explain '
'more about this rationale.' %
name.lstrip('_'))
return pull_cache[alias_name]
return None
@@ -550,4 +550,3 @@ vars_loader = PluginLoader(
C.DEFAULT_VARS_PLUGIN_PATH,
'vars_plugins',
)

View File

@@ -59,18 +59,18 @@ class ActionBase(with_metaclass(ABCMeta, object)):
'''
def __init__(self, task, connection, play_context, loader, templar, shared_loader_obj):
self._task = task
self._connection = connection
self._play_context = play_context
self._loader = loader
self._templar = templar
self._task = task
self._connection = connection
self._play_context = play_context
self._loader = loader
self._templar = templar
self._shared_loader_obj = shared_loader_obj
# Backwards compat: self._display isn't really needed, just import the global display and use that.
self._display = display
self._cleanup_remote_tmp = False
self._display = display
self._cleanup_remote_tmp = False
self._supports_check_mode = True
self._supports_async = False
self._supports_async = False
@abstractmethod
def run(self, tmp=None, task_vars=None):
@@ -154,7 +154,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
# insert shared code and arguments into the module
(module_data, module_style, module_shebang) = modify_module(module_name, module_path, module_args,
task_vars=task_vars, module_compression=self._play_context.module_compression)
task_vars=task_vars, module_compression=self._play_context.module_compression)
# FUTURE: we'll have to get fancier about this to support powershell over SSH on Windows...
if self._connection.transport == "winrm":
@@ -162,9 +162,9 @@ class ActionBase(with_metaclass(ABCMeta, object)):
final_environment = dict()
self._compute_environment_string(final_environment)
module_data = build_windows_module_payload(module_name=module_name, module_path=module_path,
b_module_data=module_data, module_args=module_args,
task_vars=task_vars, task=self._task,
play_context=self._play_context, environment=final_environment)
b_module_data=module_data, module_args=module_args,
task_vars=task_vars, task=self._task,
play_context=self._play_context, environment=final_environment)
return (module_style, module_shebang, module_data, module_path)
@@ -177,7 +177,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
if self._task.environment is not None:
environments = self._task.environment
if not isinstance(environments, list):
environments = [ environments ]
environments = [environments]
# the environments as inherited need to be reversed, to make
# sure we merge in the parent's values first so those in the
@@ -213,7 +213,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
Determines if we are required and can do pipelining
'''
if self._connection.always_pipeline_modules:
return True #eg, winrm
return True # eg, winrm
# any of these require a true
for condition in [
@@ -249,7 +249,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
if use_system_tmp:
tmpdir = None
else:
tmpdir = self._remote_expand_user(C.DEFAULT_REMOTE_TMP, sudoable=False)
tmpdir = self._remote_expand_user(C.DEFAULT_REMOTE_TMP, sudoable=False)
cmd = self._connection._shell.mkdtemp(basefile, use_system_tmp, tmp_mode, tmpdir)
result = self._low_level_execute_command(cmd, sudoable=False)
@@ -263,16 +263,16 @@ class ActionBase(with_metaclass(ABCMeta, object)):
if self._play_context.verbosity > 3:
output = u'SSH encountered an unknown error. The output was:\n%s%s' % (result['stdout'], result['stderr'])
else:
output = (u'SSH encountered an unknown error during the connection.'
' We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue')
output = (u'SSH encountered an unknown error during the connection. '
'We recommend you re-run the command using -vvvv, which will enable SSH debugging output to help diagnose the issue')
elif u'No space left on device' in result['stderr']:
output = result['stderr']
else:
output = ('Authentication or permission failure.'
' In some cases, you may have been able to authenticate and did not have permissions on the target directory.'
' Consider changing the remote temp path in ansible.cfg to a path rooted in "/tmp".'
' Failed command was: %s, exited with result %d' % (cmd, result['rc']))
output = ('Authentication or permission failure. '
'In some cases, you may have been able to authenticate and did not have permissions on the target directory. '
'Consider changing the remote temp path in ansible.cfg to a path rooted in "/tmp". '
'Failed command was: %s, exited with result %d' % (cmd, result['rc']))
if 'stdout' in result and result['stdout'] != u'':
output = output + u": %s" % result['stdout']
raise AnsibleConnectionFailure(output)
@@ -309,8 +309,8 @@ class ActionBase(with_metaclass(ABCMeta, object)):
tmp_rm_data = self._parse_returned_data(tmp_rm_res)
if tmp_rm_data.get('rc', 0) != 0:
display.warning('Error deleting remote temporary files (rc: {0}, stderr: {1})'.format(tmp_rm_res.get('rc'),
tmp_rm_res.get('stderr', 'No error string available.')))
display.warning('Error deleting remote temporary files (rc: %s, stderr: %s})'
% (tmp_rm_res.get('rc'), tmp_rm_res.get('stderr', 'No error string available.')))
def _transfer_file(self, local_path, remote_path):
self._connection.put_file(local_path, remote_path)
@@ -408,7 +408,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
setfacl_mode = 'r-x'
else:
chmod_mode = 'rX'
### Note: this form fails silently on freebsd. We currently
# NOTE: this form fails silently on freebsd. We currently
# never call _fixup_perms2() with execute=False but if we
# start to we'll have to fix this.
setfacl_mode = 'r-X'
@@ -426,22 +426,23 @@ class ActionBase(with_metaclass(ABCMeta, object)):
res = self._remote_chown(remote_paths, self._play_context.become_user)
if res['rc'] != 0 and remote_user == 'root':
# chown failed even if remove_user is root
raise AnsibleError('Failed to change ownership of the temporary files Ansible needs to create despite connecting as root.'
' Unprivileged become user would be unable to read the file.')
raise AnsibleError('Failed to change ownership of the temporary files Ansible needs to create despite connecting as root. '
'Unprivileged become user would be unable to read the file.')
elif res['rc'] != 0:
if C.ALLOW_WORLD_READABLE_TMPFILES:
# chown and fs acls failed -- do things this insecure
# way only if the user opted in in the config file
display.warning('Using world-readable permissions for temporary files Ansible needs to create when becoming an unprivileged user.'
' This may be insecure. For information on securing this, see'
' https://docs.ansible.com/ansible/become.html#becoming-an-unprivileged-user')
display.warning('Using world-readable permissions for temporary files Ansible needs to create when becoming an unprivileged user. '
'This may be insecure. For information on securing this, see '
'https://docs.ansible.com/ansible/become.html#becoming-an-unprivileged-user')
res = self._remote_chmod(remote_paths, 'a+%s' % chmod_mode)
if res['rc'] != 0:
raise AnsibleError('Failed to set file mode on remote files (rc: {0}, err: {1})'.format(res['rc'], to_native(res['stderr'])))
else:
raise AnsibleError('Failed to set permissions on the temporary files Ansible needs to create when becoming an unprivileged user'
' (rc: {0}, err: {1}). For information on working around this,'
' see https://docs.ansible.com/ansible/become.html#becoming-an-unprivileged-user'.format(res['rc'], to_native(res['stderr'])))
raise AnsibleError('Failed to set permissions on the temporary files Ansible needs to create when becoming an unprivileged user '
'(rc: %s, err: %s}). For information on working around this, see '
'https://docs.ansible.com/ansible/become.html#becoming-an-unprivileged-user'
% (res['rc'], to_native(res['stderr'])))
elif execute:
# Can't depend on the file being transferred with execute permissions.
# Only need user perms because no become was used here
@@ -479,7 +480,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
'''
Get information from remote file.
'''
module_args=dict(
module_args = dict(
path=path,
follow=follow,
get_md5=False,
@@ -534,7 +535,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
elif errormsg.endswith(u'MODULE FAILURE'):
x = "4" # python not found or module uncaught exception
elif 'json' in errormsg or 'simplejson' in errormsg:
x = "5" # json or simplejson modules needed
x = "5" # json or simplejson modules needed
finally:
return x
@@ -611,8 +612,6 @@ class ActionBase(with_metaclass(ABCMeta, object)):
# give the module the socket for persistent connections
module_args['_ansible_socket'] = task_vars.get('ansible_socket')
def _execute_module(self, module_name=None, module_args=None, tmp=None, task_vars=None, persist_files=False, delete_remote_tmp=True, wrap_async=False):
'''
Transfer and run a module along with its arguments.
@@ -641,7 +640,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
if not self._is_pipelining_enabled(module_style, wrap_async):
# we might need remote tmp dir
if not tmp or not 'tmp' in tmp:
if not tmp or 'tmp' not in tmp:
tmp = self._make_tmp_path()
remote_module_filename = self._connection._shell.get_remote_filename(module_path)
@@ -661,7 +660,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
# we need to dump the module args to a k=v string in a file on
# the remote system, which can be read and parsed by the module
args_data = ""
for k,v in iteritems(module_args):
for k, v in iteritems(module_args):
args_data += '%s=%s ' % (k, shlex_quote(text_type(v)))
self._transfer_data(args_file_path, args_data)
elif module_style in ('non_native_want_json', 'binary'):
@@ -690,7 +689,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
remote_files.append(remote_async_module_path)
async_limit = self._task.async
async_jid = str(random.randint(0, 999999999999))
async_jid = str(random.randint(0, 999999999999))
# call the interpreter for async_wrapper directly
# this permits use of a script for an interpreter on non-Linux platforms
@@ -710,7 +709,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
if not self._should_remove_tmp_path(tmp):
async_cmd.append("-preserve_tmp")
cmd= " ".join(to_text(x) for x in async_cmd)
cmd = " ".join(to_text(x) for x in async_cmd)
else:
@@ -736,7 +735,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
# Fix permissions of the tmp path and tmp files. This should be called after all files have been transferred.
if remote_files:
# remove none/empty
remote_files = [ x for x in remote_files if x]
remote_files = [x for x in remote_files if x]
self._fixup_perms2(remote_files, self._play_context.remote_user)
# actually execute
@@ -745,7 +744,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
# parse the main result
data = self._parse_returned_data(res)
#NOTE: INTERNAL KEYS ONLY ACCESSIBLE HERE
# NOTE: INTERNAL KEYS ONLY ACCESSIBLE HERE
# get internal info before cleaning
tmpdir_delete = (not data.pop("_ansible_suppress_tmpdir_delete", False) and wrap_async)
@@ -756,7 +755,7 @@ class ActionBase(with_metaclass(ABCMeta, object)):
if (self._play_context.become and self._play_context.become_user != 'root') and not persist_files and delete_remote_tmp or tmpdir_delete:
self._remove_tmp_path(tmp)
#FIXME: for backwards compat, figure out if still makes sense
# FIXME: for backwards compat, figure out if still makes sense
if wrap_async:
data['changed'] = True
@@ -784,7 +783,6 @@ class ActionBase(with_metaclass(ABCMeta, object)):
if key in data and not data[key]:
del data[key]
def _clean_returned_data(self, data):
remove_keys = set()
fact_keys = set(data.keys())

View File

@@ -22,7 +22,6 @@ __metaclass__ = type
from ansible.plugins.action import ActionBase
from ansible.plugins.action.net_config import ActionModule as NetActionModule
class ActionModule(NetActionModule, ActionBase):
pass

View File

@@ -22,5 +22,6 @@ __metaclass__ = type
from ansible.plugins.action import ActionBase
from ansible.plugins.action.net_template import ActionModule as NetActionModule
class ActionModule(NetActionModule, ActionBase):
pass

View File

@@ -87,14 +87,14 @@ class ActionModule(ActionBase):
if task_vars is None:
task_vars = dict()
src = self._task.args.get('src', None)
dest = self._task.args.get('dest', None)
delimiter = self._task.args.get('delimiter', None)
src = self._task.args.get('src', None)
dest = self._task.args.get('dest', None)
delimiter = self._task.args.get('delimiter', None)
remote_src = self._task.args.get('remote_src', 'yes')
regexp = self._task.args.get('regexp', None)
follow = self._task.args.get('follow', False)
regexp = self._task.args.get('regexp', None)
follow = self._task.args.get('follow', False)
ignore_hidden = self._task.args.get('ignore_hidden', False)
decrypt = self._task.args.get('decrypt', True)
decrypt = self._task.args.get('decrypt', True)
if src is None or dest is None:
result['failed'] = True
@@ -159,7 +159,7 @@ class ActionModule(ActionBase):
# fix file permissions when the copy is done as a different user
self._fixup_perms2((tmp, remote_path))
new_module_args.update( dict( src=xfered,))
new_module_args.update(dict(src=xfered,))
res = self._execute_module(module_name='copy', module_args=new_module_args, task_vars=task_vars, tmp=tmp, delete_remote_tmp=False)
if diff:

View File

@@ -40,13 +40,13 @@ class ActionModule(ActionBase):
result = super(ActionModule, self).run(tmp, task_vars)
source = self._task.args.get('src', None)
source = self._task.args.get('src', None)
content = self._task.args.get('content', None)
dest = self._task.args.get('dest', None)
raw = boolean(self._task.args.get('raw', 'no'))
force = boolean(self._task.args.get('force', 'yes'))
dest = self._task.args.get('dest', None)
raw = boolean(self._task.args.get('raw', 'no'))
force = boolean(self._task.args.get('force', 'yes'))
remote_src = boolean(self._task.args.get('remote_src', False))
follow = boolean(self._task.args.get('follow', False))
follow = boolean(self._task.args.get('follow', False))
decrypt = boolean(self._task.args.get('decrypt', True))
result['failed'] = True
@@ -256,8 +256,8 @@ class ActionModule(ActionBase):
del new_module_args[key]
module_return = self._execute_module(module_name='copy',
module_args=new_module_args, task_vars=task_vars,
tmp=tmp, delete_remote_tmp=delete_remote_tmp)
module_args=new_module_args, task_vars=task_vars,
tmp=tmp, delete_remote_tmp=delete_remote_tmp)
module_executed = True
else:
@@ -291,8 +291,8 @@ class ActionModule(ActionBase):
# Execute the file module.
module_return = self._execute_module(module_name='file',
module_args=new_module_args, task_vars=task_vars,
tmp=tmp, delete_remote_tmp=delete_remote_tmp)
module_args=new_module_args, task_vars=task_vars,
tmp=tmp, delete_remote_tmp=delete_remote_tmp)
module_executed = True
if not module_return.get('checksum'):

View File

@@ -27,6 +27,7 @@ import urlparse
from ansible.module_utils._text import to_text
from ansible.plugins.action.eos import ActionModule as _ActionModule
class ActionModule(_ActionModule):
def run(self, tmp=None, task_vars=None):

View File

@@ -42,10 +42,10 @@ class ActionModule(ActionBase):
result['msg'] = 'check mode not (yet) supported for this module'
return result
source = self._task.args.get('src', None)
dest = self._task.args.get('dest', None)
flat = boolean(self._task.args.get('flat'))
fail_on_missing = boolean(self._task.args.get('fail_on_missing'))
source = self._task.args.get('src', None)
dest = self._task.args.get('dest', None)
flat = boolean(self._task.args.get('flat'))
fail_on_missing = boolean(self._task.args.get('fail_on_missing'))
validate_checksum = boolean(self._task.args.get('validate_checksum', self._task.args.get('validate_md5', True)))
# validate_md5 is the deprecated way to specify validate_checksum
@@ -120,7 +120,7 @@ class ActionModule(ActionBase):
target_name = self._play_context.remote_addr
dest = "%s/%s/%s" % (self._loader.path_dwim(dest), target_name, source_local)
dest = dest.replace("//","/")
dest = dest.replace("//", "/")
if remote_checksum in ('0', '1', '2', '3', '4', '5'):
result['changed'] = False
@@ -175,8 +175,8 @@ class ActionModule(ActionBase):
if validate_checksum and new_checksum != remote_checksum:
result.update(dict(failed=True, md5sum=new_md5,
msg="checksum mismatch", file=source, dest=dest, remote_md5sum=None,
checksum=new_checksum, remote_checksum=remote_checksum))
msg="checksum mismatch", file=source, dest=dest, remote_md5sum=None,
checksum=new_checksum, remote_checksum=remote_checksum))
else:
result.update({'changed': True, 'md5sum': new_md5, 'dest': dest,
'remote_md5sum': None, 'checksum': new_checksum,

View File

@@ -23,7 +23,7 @@ from ansible.plugins.action import ActionBase
class ActionModule(ActionBase):
''' Create inventory groups based on variables '''
### We need to be able to modify the inventory
# We need to be able to modify the inventory
TRANSFERS_FILES = False
def run(self, tmp=None, task_vars=None):
@@ -38,7 +38,7 @@ class ActionModule(ActionBase):
return result
group_name = self._task.args.get('key')
group_name = group_name.replace(' ','-')
group_name = group_name.replace(' ', '-')
result['changed'] = False
result['add_group'] = group_name

View File

@@ -27,6 +27,7 @@ import urlparse
from ansible.module_utils._text import to_text
from ansible.plugins.action.ios import ActionModule as _ActionModule
class ActionModule(_ActionModule):
def run(self, tmp=None, task_vars=None):

View File

@@ -27,6 +27,7 @@ import urlparse
from ansible.module_utils._text import to_text
from ansible.plugins.action.iosxr import ActionModule as _ActionModule
class ActionModule(_ActionModule):
def run(self, tmp=None, task_vars=None):
@@ -100,4 +101,3 @@ class ActionModule(_ActionModule):
searchpath.append(os.path.dirname(source))
self._templar.environment.loader.searchpath = searchpath
self._task.args['src'] = self._templar.template(template_data)

View File

@@ -112,7 +112,7 @@ class ActionModule(_ActionModule):
path = unfrackpath("$HOME/.ansible/pc")
# use play_context.connection instea of play_context.port to avoid
# collision if netconf is listening on port 22
#cp = ssh._create_control_path(play_context.remote_addr, play_context.connection, play_context.remote_user)
# cp = ssh._create_control_path(play_context.remote_addr, play_context.connection, play_context.remote_user)
cp = ssh._create_control_path(play_context.remote_addr, play_context.port, play_context.remote_user)
return cp % dict(directory=path)

View File

@@ -27,6 +27,7 @@ import urlparse
from ansible.module_utils._text import to_text
from ansible.plugins.action.junos import ActionModule as _ActionModule
class ActionModule(_ActionModule):
def run(self, tmp=None, task_vars=None):

View File

@@ -27,7 +27,7 @@ class ActionModule(ActionBase):
# individual modules might disagree but as the generic the action plugin, pass at this point.
self._supports_check_mode = True
self._supports_async = True
self._supports_async = True
results = super(ActionModule, self).run(tmp, task_vars)

View File

@@ -27,6 +27,7 @@ import urlparse
from ansible.module_utils._text import to_text
from ansible.plugins.action.nxos import ActionModule as _ActionModule
class ActionModule(_ActionModule):
def run(self, tmp=None, task_vars=None):

View File

@@ -22,7 +22,6 @@ __metaclass__ = type
from ansible.plugins.action import ActionBase
from ansible.plugins.action.net_config import ActionModule as NetActionModule
class ActionModule(NetActionModule, ActionBase):
pass

View File

@@ -38,7 +38,7 @@ class ActionModule(NetActionModule, ActionBase):
self._handle_template()
result.update(self._execute_module(module_name=self._task.action,
module_args=self._task.args, task_vars=task_vars))
module_args=self._task.args, task_vars=task_vars))
if self._task.args.get('backup') and result.get('_backup'):
contents = json.dumps(result['_backup'], indent=4)
@@ -48,5 +48,3 @@ class ActionModule(NetActionModule, ActionBase):
del result['_backup']
return result

View File

@@ -34,7 +34,7 @@ class ActionModule(ActionBase):
''' handler for package operations '''
self._supports_check_mode = True
self._supports_async = True
self._supports_async = True
result = super(ActionModule, self).run(tmp, task_vars)
@@ -42,12 +42,12 @@ class ActionModule(ActionBase):
if module == 'auto':
try:
if self._task.delegate_to: # if we delegate, we should use delegated host's facts
if self._task.delegate_to: # if we delegate, we should use delegated host's facts
module = self._templar.template("{{hostvars['%s']['ansible_facts']['ansible_pkg_mgr']}}" % self._task.delegate_to)
else:
module = self._templar.template('{{ansible_facts["ansible_pkg_mgr"]}}')
except:
pass # could not get it from template!
pass # could not get it from template!
if module == 'auto':
facts = self._execute_module(module_name='setup', module_args=dict(filter='ansible_pkg_mgr', gather_subset='!all'), task_vars=task_vars)

View File

@@ -34,7 +34,7 @@ class ActionModule(ActionBase):
result = super(ActionModule, self).run(tmp, task_vars)
src = self._task.args.get('src', None)
src = self._task.args.get('src', None)
remote_src = boolean(self._task.args.get('remote_src', 'no'))
if src is None:
@@ -61,7 +61,7 @@ class ActionModule(ActionBase):
tmp_src = self._connection._shell.join_path(tmp, os.path.basename(src))
self._transfer_file(src, tmp_src)
self._fixup_perms2((tmp, tmp_src) )
self._fixup_perms2((tmp, tmp_src))
new_module_args = self._task.args.copy()
new_module_args.update(

View File

@@ -59,13 +59,13 @@ class ActionModule(ActionBase):
prompt = None
seconds = None
result.update(dict(
changed = False,
rc = 0,
stderr = '',
stdout = '',
start = None,
stop = None,
delta = None,
changed=False,
rc=0,
stderr='',
stdout='',
start=None,
stop=None,
delta=None,
))
# Is 'args' empty, then this is the default prompted pause
@@ -163,7 +163,6 @@ class ActionModule(ActionBase):
else:
raise AnsibleError('user requested abort!')
except AnsibleTimeoutExceeded:
# this is the exception we expect when the alarm signal
# fires, so we simply ignore it to move into the cleanup

View File

@@ -59,9 +59,9 @@ class ActionModule(ActionBase):
# out now so we know the file name we need to transfer to the remote,
# and everything else is an argument to the script which we need later
# to append to the remote command
parts = self._task.args.get('_raw_params', '').strip().split()
parts = self._task.args.get('_raw_params', '').strip().split()
source = parts[0]
args = ' '.join(parts[1:])
args = ' '.join(parts[1:])
try:
source = self._loader.get_real_file(self._find_needle('files', source), decrypt=self._task.args.get('decrypt', True))

View File

@@ -33,7 +33,7 @@ class ActionModule(ActionBase):
''' handler for package operations '''
self._supports_check_mode = True
self._supports_async = True
self._supports_async = True
result = super(ActionModule, self).run(tmp, task_vars)
@@ -41,12 +41,12 @@ class ActionModule(ActionBase):
if module == 'auto':
try:
if self._task.delegate_to: # if we delegate, we should use delegated host's facts
if self._task.delegate_to: # if we delegate, we should use delegated host's facts
module = self._templar.template("{{hostvars['%s']['ansible_facts']['ansible_service_mgr']}}" % self._task.delegate_to)
else:
module = self._templar.template('{{ansible_facts["ansible_service_mgr"]}}')
except:
pass # could not get it from template!
pass # could not get it from template!
if module == 'auto':
facts = self._execute_module(module_name='setup', module_args=dict(gather_subset='!all', filter='ansible_service_mgr'), task_vars=task_vars)

View File

@@ -28,7 +28,7 @@ class ActionModule(ActionBase):
TRANSFERS_FILES = False
#TODO: document this in non-empty set_stats.py module
# TODO: document this in non-empty set_stats.py module
def run(self, tmp=None, task_vars=None):
if task_vars is None:
task_vars = dict()

View File

@@ -19,14 +19,14 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import glob
import os
import re
import time
import glob
from ansible.plugins.action.sros import ActionModule as _ActionModule
from ansible.module_utils._text import to_text
from ansible.module_utils.six.moves.urllib.parse import urlsplit
from ansible.module_utils._text import to_text
from ansible.plugins.action.sros import ActionModule as _ActionModule
from ansible.utils.vars import merge_hash
PRIVATE_KEYS_RE = re.compile('__.+__')
@@ -110,4 +110,3 @@ class ActionModule(_ActionModule):
searchpath.append(os.path.dirname(source))
self._templar.environment.loader.searchpath = searchpath
self._task.args['src'] = self._templar.template(template_data)

View File

@@ -62,7 +62,7 @@ class ActionModule(ActionBase):
return path
# If using docker, do not add user information
if self._remote_transport not in [ 'docker' ] and user:
if self._remote_transport not in ['docker'] and user:
user_prefix = '%s@' % (user, )
if self._host_is_ipv6_address(host):
@@ -308,8 +308,7 @@ class ActionModule(ActionBase):
src = _tmp_args.get('src', None)
dest = _tmp_args.get('dest', None)
if src is None or dest is None:
return dict(failed=True,
msg="synchronize requires both src and dest parameters are set")
return dict(failed=True, msg="synchronize requires both src and dest parameters are set")
if not dest_is_local:
# Private key handling
@@ -384,7 +383,7 @@ class ActionModule(ActionBase):
# If launching synchronize against docker container
# use rsync_opts to support container to override rsh options
if self._remote_transport in [ 'docker' ]:
if self._remote_transport in ['docker']:
# Replicate what we do in the module argumentspec handling for lists
if not isinstance(_tmp_args.get('rsync_opts'), MutableSequence):
tmp_rsync_opts = _tmp_args.get('rsync_opts', [])

View File

@@ -23,11 +23,12 @@ from ansible import constants as C
from ansible.errors import AnsibleError
from ansible.module_utils._text import to_bytes, to_native, to_text
from ansible.plugins.action import ActionBase
from ansible.utils.hashing import checksum_s
from ansible.template import generate_ansible_template_vars
from ansible.utils.hashing import checksum_s
boolean = C.mk_boolean
class ActionModule(ActionBase):
TRANSFERS_FILES = True
@@ -56,9 +57,9 @@ class ActionModule(ActionBase):
result = super(ActionModule, self).run(tmp, task_vars)
source = self._task.args.get('src', None)
dest = self._task.args.get('dest', None)
force = boolean(self._task.args.get('force', True))
state = self._task.args.get('state', None)
dest = self._task.args.get('dest', None)
force = boolean(self._task.args.get('force', True))
state = self._task.args.get('state', None)
newline_sequence = self._task.args.get('newline_sequence', self.DEFAULT_NEWLINE_SEQUENCE)
variable_start_string = self._task.args.get('variable_start_string', None)
variable_end_string = self._task.args.get('variable_end_string', None)
@@ -191,7 +192,7 @@ class ActionModule(ActionBase):
dest=dest,
original_basename=os.path.basename(source),
follow=True,
),
),
)
result.update(self._execute_module(module_name='copy', module_args=new_module_args, task_vars=task_vars, tmp=tmp, delete_remote_tmp=False))

View File

@@ -38,8 +38,8 @@ class ActionModule(ActionBase):
result = super(ActionModule, self).run(tmp, task_vars)
source = self._task.args.get('src', None)
dest = self._task.args.get('dest', None)
source = self._task.args.get('src', None)
dest = self._task.args.get('dest', None)
remote_src = boolean(self._task.args.get('remote_src', False))
creates = self._task.args.get('creates', None)
decrypt = self._task.args.get('decrypt', True)
@@ -73,7 +73,7 @@ class ActionModule(ActionBase):
self._remove_tmp_path(tmp)
return result
dest = self._remote_expand_user(dest) # CCTODO: Fix path for Windows hosts.
dest = self._remote_expand_user(dest) # CCTODO: Fix path for Windows hosts.
source = os.path.expanduser(source)
if not remote_src:

View File

@@ -86,13 +86,13 @@ class BaseFileCacheModule(BaseCacheModule):
self._cache_dir = os.path.expanduser(os.path.expandvars(C.CACHE_PLUGIN_CONNECTION))
if not self._cache_dir:
raise AnsibleError("error, '%s' cache plugin requires the 'fact_caching_connection' config option"
" to be set (to a writeable directory path)" % self.plugin_name)
raise AnsibleError("error, '%s' cache plugin requires the 'fact_caching_connection' config option "
"to be set (to a writeable directory path)" % self.plugin_name)
if not os.path.exists(self._cache_dir):
try:
os.makedirs(self._cache_dir)
except (OSError,IOError) as e:
except (OSError, IOError) as e:
raise AnsibleError("error in '%s' cache plugin while trying to create cache dir %s : %s" % (self.plugin_name, self._cache_dir, to_bytes(e)))
else:
for x in (os.R_OK, os.W_OK, os.X_OK):
@@ -118,12 +118,12 @@ class BaseFileCacheModule(BaseCacheModule):
self._cache[key] = value
return value
except ValueError as e:
display.warning("error in '%s' cache plugin while trying to read %s : %s."
" Most likely a corrupt file, so erasing and failing." % (self.plugin_name, cachefile, to_bytes(e)))
display.warning("error in '%s' cache plugin while trying to read %s : %s. "
"Most likely a corrupt file, so erasing and failing." % (self.plugin_name, cachefile, to_bytes(e)))
self.delete(key)
raise AnsibleError("The cache file %s was corrupt, or did not otherwise contain valid data."
" It has been removed, so you can re-run your command now." % cachefile)
except (OSError,IOError) as e:
raise AnsibleError("The cache file %s was corrupt, or did not otherwise contain valid data. "
"It has been removed, so you can re-run your command now." % cachefile)
except (OSError, IOError) as e:
display.warning("error in '%s' cache plugin while trying to read %s : %s" % (self.plugin_name, cachefile, to_bytes(e)))
raise KeyError
except Exception as e:
@@ -136,7 +136,7 @@ class BaseFileCacheModule(BaseCacheModule):
cachefile = "%s/%s" % (self._cache_dir, key)
try:
self._dump(value, cachefile)
except (OSError,IOError) as e:
except (OSError, IOError) as e:
display.warning("error in '%s' cache plugin while trying to write to %s : %s" % (self.plugin_name, cachefile, to_bytes(e)))
def has_expired(self, key):
@@ -147,7 +147,7 @@ class BaseFileCacheModule(BaseCacheModule):
cachefile = "%s/%s" % (self._cache_dir, key)
try:
st = os.stat(cachefile)
except (OSError,IOError) as e:
except (OSError, IOError) as e:
if e.errno == errno.ENOENT:
return False
else:
@@ -179,7 +179,7 @@ class BaseFileCacheModule(BaseCacheModule):
try:
os.stat(cachefile)
return True
except (OSError,IOError) as e:
except (OSError, IOError) as e:
if e.errno == errno.ENOENT:
return False
else:
@@ -194,7 +194,7 @@ class BaseFileCacheModule(BaseCacheModule):
try:
os.remove("%s/%s" % (self._cache_dir, key))
except (OSError, IOError):
pass #TODO: only pass on non existing?
pass # TODO: only pass on non existing?
def flush(self):
self._cache = {}
@@ -236,6 +236,7 @@ class BaseFileCacheModule(BaseCacheModule):
"""
pass
class FactCache(MutableMapping):
def __init__(self, *args, **kwargs):
@@ -247,7 +248,6 @@ class FactCache(MutableMapping):
# Backwards compat: self._display isn't really needed, just import the global display and use that.
self._display = display
def __getitem__(self, key):
if not self._plugin.contains(key):
raise KeyError

View File

@@ -19,4 +19,3 @@ __metaclass__ = type
# moved actual classes to __init__ kept here for backward compat with 3rd parties
from ansible.plugins.cache import BaseCacheModule, BaseFileCacheModule

View File

@@ -37,6 +37,7 @@ except ImportError:
from ansible.parsing.utils.jsonify import jsonify
from ansible.plugins.cache import BaseFileCacheModule
class CacheModule(BaseFileCacheModule):
"""
A caching module backed by json files.

View File

@@ -30,6 +30,7 @@ __metaclass__ = type
from ansible.plugins.cache import BaseCacheModule
class CacheModule(BaseCacheModule):
def __init__(self, *args, **kwargs):

View File

@@ -36,6 +36,7 @@ except ImportError:
from ansible.module_utils.six import PY3
from ansible.plugins.cache import BaseFileCacheModule
class CacheModule(BaseFileCacheModule):
"""
A caching module backed by pickle files.

View File

@@ -30,6 +30,7 @@ try:
except ImportError:
raise AnsibleError("The 'redis' python module is required for the redis fact cache, 'pip install redis'")
class CacheModule(BaseCacheModule):
"""
A caching module backed by redis.
@@ -65,7 +66,7 @@ class CacheModule(BaseCacheModule):
def set(self, key, value):
value2 = json.dumps(value)
if self._timeout > 0: # a timeout of 0 is handled as meaning 'never expire'
if self._timeout > 0: # a timeout of 0 is handled as meaning 'never expire'
self._cache.setex(self._make_key(key), int(self._timeout), value2)
else:
self._cache.set(self._make_key(key), value2)

View File

@@ -37,6 +37,7 @@ from ansible.parsing.yaml.loader import AnsibleLoader
from ansible.parsing.yaml.dumper import AnsibleDumper
from ansible.plugins.cache import BaseFileCacheModule
class CacheModule(BaseFileCacheModule):
"""
A caching module backed by yaml files.

View File

@@ -213,7 +213,6 @@ class CallbackBase:
if remove_key in result:
del result[remove_key]
def set_play_context(self, play_context):
pass
@@ -280,7 +279,7 @@ class CallbackBase:
def on_file_diff(self, host, diff):
pass
####### V2 METHODS, by default they call v1 counterparts if possible ######
# V2 METHODS, by default they call v1 counterparts if possible
def v2_on_any(self, *args, **kwargs):
self.on_any(args, kwargs)
@@ -295,7 +294,7 @@ class CallbackBase:
def v2_runner_on_skipped(self, result):
if C.DISPLAY_SKIPPED_HOSTS:
host = result._host.get_name()
self.runner_on_skipped(host, self._get_item(getattr(result._result,'results',{})))
self.runner_on_skipped(host, self._get_item(getattr(result._result, 'results', {})))
def v2_runner_on_unreachable(self, result):
host = result._host.get_name()
@@ -307,7 +306,7 @@ class CallbackBase:
def v2_runner_on_async_poll(self, result):
host = result._host.get_name()
jid = result._result.get('ansible_job_id')
#FIXME, get real clock
# FIXME, get real clock
clock = 0
self.runner_on_async_poll(host, result._result, jid, clock)
@@ -322,7 +321,7 @@ class CallbackBase:
self.runner_on_async_failed(host, result._result, jid)
def v2_runner_on_file_diff(self, result, diff):
pass #no v1 correspondance
pass # no v1 correspondance
def v2_playbook_on_start(self, playbook):
self.playbook_on_start()
@@ -341,10 +340,10 @@ class CallbackBase:
self.playbook_on_task_start(task.name, is_conditional)
def v2_playbook_on_cleanup_task_start(self, task):
pass #no v1 correspondance
pass # no v1 correspondance
def v2_playbook_on_handler_task_start(self, task):
pass #no v1 correspondance
pass # no v1 correspondance
def v2_playbook_on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None):
self.playbook_on_vars_prompt(varname, private, prompt, encrypt, confirm, salt_size, salt, default)
@@ -372,7 +371,7 @@ class CallbackBase:
self.on_file_diff(host, result._result['diff'])
def v2_playbook_on_include(self, included_file):
pass #no v1 correspondance
pass # no v1 correspondance
def v2_runner_item_on_ok(self, result):
pass

View File

@@ -21,6 +21,7 @@ __metaclass__ = type
from ansible.plugins.callback.default import CallbackModule as CallbackModule_default
class CallbackModule(CallbackModule_default):
CALLBACK_VERSION = 2.0
@@ -76,4 +77,3 @@ class CallbackModule(CallbackModule_default):
def v2_runner_item_on_failed(self, result):
self.display_task_banner()
self.super_ref.v2_runner_item_on_failed(result)

View File

@@ -21,6 +21,7 @@ __metaclass__ = type
from ansible.plugins.callback import CallbackBase
class CallbackModule(CallbackBase):
"""
This is a very trivial example of how any callback function can get at play and task objects.

View File

@@ -30,6 +30,7 @@ from ansible import constants as C
from ansible.plugins.callback import CallbackBase
from ansible.utils.color import colorize, hostcolor
class CallbackModule(CallbackBase):
'''
@@ -100,7 +101,7 @@ class CallbackModule(CallbackBase):
self._process_items(result)
else:
if (self._display.verbosity > 0 or '_ansible_verbose_always' in result._result) and not '_ansible_verbose_override' in result._result:
if (self._display.verbosity > 0 or '_ansible_verbose_always' in result._result) and '_ansible_verbose_override' not in result._result:
msg += " => %s" % (self._dump_results(result._result),)
self._display.display(msg, color=color)
@@ -113,7 +114,7 @@ class CallbackModule(CallbackBase):
self._process_items(result)
else:
msg = "skipping: [%s]" % result._host.get_name()
if (self._display.verbosity > 0 or '_ansible_verbose_always' in result._result) and not '_ansible_verbose_override' in result._result:
if (self._display.verbosity > 0 or '_ansible_verbose_always' in result._result) and '_ansible_verbose_override' not in result._result:
msg += " => %s" % self._dump_results(result._result)
self._display.display(msg, color=C.COLOR_SKIP)
@@ -209,7 +210,7 @@ class CallbackModule(CallbackBase):
msg += " => (item=%s)" % (self._get_item(result._result),)
if (self._display.verbosity > 0 or '_ansible_verbose_always' in result._result) and not '_ansible_verbose_override' in result._result:
if (self._display.verbosity > 0 or '_ansible_verbose_always' in result._result) and '_ansible_verbose_override' not in result._result:
msg += " => %s" % self._dump_results(result._result)
self._display.display(msg, color=color)
@@ -230,7 +231,7 @@ class CallbackModule(CallbackBase):
def v2_runner_item_on_skipped(self, result):
if C.DISPLAY_SKIPPED_HOSTS:
msg = "skipping: [%s] => (item=%s) " % (result._host.get_name(), self._get_item(result._result))
if (self._display.verbosity > 0 or '_ansible_verbose_always' in result._result) and not '_ansible_verbose_override' in result._result:
if (self._display.verbosity > 0 or '_ansible_verbose_always' in result._result) and '_ansible_verbose_override' not in result._result:
msg += " => %s" % self._dump_results(result._result)
self._display.display(msg, color=C.COLOR_SKIP)
@@ -269,16 +270,16 @@ class CallbackModule(CallbackBase):
if C.SHOW_CUSTOM_STATS and stats.custom:
self._display.banner("CUSTOM STATS: ")
# per host
#TODO: come up with 'pretty format'
# TODO: come up with 'pretty format'
for k in sorted(stats.custom.keys()):
if k == '_run':
continue
self._display.display('\t%s: %s' % (k, self._dump_results(stats.custom[k], indent=1).replace('\n','')))
self._display.display('\t%s: %s' % (k, self._dump_results(stats.custom[k], indent=1).replace('\n', '')))
# print per run custom stats
if '_run' in stats.custom:
self._display.display("", screen_only=True)
self._display.display('\tRUN: %s' % self._dump_results(stats.custom['_run'], indent=1).replace('\n',''))
self._display.display('\tRUN: %s' % self._dump_results(stats.custom['_run'], indent=1).replace('\n', ''))
self._display.display("", screen_only=True)
def v2_playbook_on_start(self, playbook):
@@ -291,13 +292,13 @@ class CallbackModule(CallbackBase):
for option in dir(self._options):
if option.startswith('_') or option in ['read_file', 'ensure_value', 'read_module']:
continue
val = getattr(self._options,option)
val = getattr(self._options, option)
if val:
self._display.vvvv('%s: %s' % (option,val))
self._display.vvvv('%s: %s' % (option, val))
def v2_runner_retry(self, result):
task_name = result.task_name or result._task
msg = "FAILED - RETRYING: %s (%d retries left)." % (task_name, result._result['retries'] - result._result['attempts'])
if (self._display.verbosity > 2 or '_ansible_verbose_always' in result._result) and not '_ansible_verbose_override' in result._result:
if (self._display.verbosity > 2 or '_ansible_verbose_always' in result._result) and '_ansible_verbose_override' not in result._result:
msg += "Result was: %s" % self._dump_results(result._result)
self._display.display(msg, color=C.COLOR_DEBUG)

View File

@@ -71,18 +71,18 @@ import sys
# FIXME: Importing constants as C simply does not work, beats me :-/
#from ansible import constants as C
# from ansible import constants as C
class C:
COLOR_HIGHLIGHT = 'white'
COLOR_VERBOSE = 'blue'
COLOR_WARN = 'bright purple'
COLOR_ERROR = 'red'
COLOR_DEBUG = 'dark gray'
COLOR_DEPRECATE = 'purple'
COLOR_SKIP = 'cyan'
COLOR_HIGHLIGHT = 'white'
COLOR_VERBOSE = 'blue'
COLOR_WARN = 'bright purple'
COLOR_ERROR = 'red'
COLOR_DEBUG = 'dark gray'
COLOR_DEPRECATE = 'purple'
COLOR_SKIP = 'cyan'
COLOR_UNREACHABLE = 'bright red'
COLOR_OK = 'green'
COLOR_CHANGED = 'yellow'
COLOR_OK = 'green'
COLOR_CHANGED = 'yellow'
# Taken from Dstat
@@ -136,15 +136,16 @@ class vt100:
colors = dict(
ok = vt100.darkgreen,
changed = vt100.darkyellow,
skipped = vt100.darkcyan,
ignored = vt100.cyanbg + vt100.red,
failed = vt100.darkred,
unreachable = vt100.red,
ok=vt100.darkgreen,
changed=vt100.darkyellow,
skipped=vt100.darkcyan,
ignored=vt100.cyanbg + vt100.red,
failed=vt100.darkred,
unreachable=vt100.red,
)
states = ( 'skipped', 'ok', 'changed', 'failed', 'unreachable' )
states = ('skipped', 'ok', 'changed', 'failed', 'unreachable')
class CallbackModule_dense(CallbackModule_default):
@@ -156,7 +157,6 @@ class CallbackModule_dense(CallbackModule_default):
CALLBACK_TYPE = 'stdout'
CALLBACK_NAME = 'dense'
def __init__(self):
# From CallbackModule

View File

@@ -123,11 +123,17 @@ class CallbackModule(CallbackBase):
level = 'err'
else:
level = 'notice' if 'changed' in msg and msg['changed'] else 'info'
logs.append({"log": {
'sources': {'source': source},
'messages': {'message': json.dumps(msg)},
'level': level
}})
logs.append({
"log": {
'sources': {
'source': source
},
'messages': {
'message': json.dumps(msg)
},
'level': level
}
})
return logs
def send_reports(self, stats):
@@ -154,8 +160,8 @@ class CallbackModule(CallbackBase):
"metrics": metrics,
"status": status,
"logs": log,
}
}
}
# To be changed to /api/v2/config_reports in 1.11. Maybe we
# could make a GET request to get the Foreman version & do
# this automatically.

View File

@@ -58,7 +58,7 @@ class CallbackModule(CallbackBase):
if not HAS_PRETTYTABLE:
self.disabled = True
self._display.warning('The `prettytable` python module is not installed. '
'Disabling the HipChat callback plugin.')
'Disabling the HipChat callback plugin.')
self.msg_uri = 'https://api.hipchat.com/v1/rooms/message'
self.token = os.getenv('HIPCHAT_TOKEN')
@@ -69,8 +69,8 @@ class CallbackModule(CallbackBase):
if self.token is None:
self.disabled = True
self._display.warning('HipChat token could not be loaded. The HipChat '
'token can be provided using the `HIPCHAT_TOKEN` '
'environment variable.')
'token can be provided using the `HIPCHAT_TOKEN` '
'environment variable.')
self.printed_playbook = False
self.playbook_name = None

View File

@@ -39,8 +39,8 @@ class CallbackModule(CallbackBase):
super(CallbackModule, self).__init__(display=display)
if not HAS_XMPP:
self._display.warning("The required python xmpp library (xmpppy) is not installed."
" pip install git+https://github.com/ArchipelProject/xmpppy")
self._display.warning("The required python xmpp library (xmpppy) is not installed. "
"pip install git+https://github.com/ArchipelProject/xmpppy")
self.disabled = True
self.serv = os.getenv('JABBER_SERV')
@@ -48,15 +48,15 @@ class CallbackModule(CallbackBase):
self.j_pass = os.getenv('JABBER_PASS')
self.j_to = os.getenv('JABBER_TO')
if (self.j_user or self.j_pass or self.serv ) is None:
if (self.j_user or self.j_pass or self.serv) is None:
self.disabled = True
self._display.warning ('Jabber CallBack want JABBER_USER and JABBER_PASS env variables')
self._display.warning('Jabber CallBack want JABBER_USER and JABBER_PASS env variables')
def send_msg(self, msg):
"""Send message"""
jid = xmpp.JID(self.j_user)
client = xmpp.Client(self.serv,debug=[])
client.connect(server=(self.serv,5222))
client = xmpp.Client(self.serv, debug=[])
client.connect(server=(self.serv, 5222))
client.auth(jid.getNode(), self.j_pass, resource=jid.getResource())
message = xmpp.Message(self.j_to, msg)
message.setAttr('type', 'chat')
@@ -93,5 +93,4 @@ class CallbackModule(CallbackBase):
self.send_msg("%s: Failures detected \n%s \nHost: %s\n Failed at:\n%s" % (name, self.task, h, out))
else:
out = self.debug
self.send_msg("Great! \n Playbook %s completed:\n%s \n Last task debug:\n %s" % (name,s, out))
self.send_msg("Great! \n Playbook %s completed:\n%s \n Last task debug:\n %s" % (name, s, out))

View File

@@ -44,8 +44,8 @@ class CallbackModule(CallbackBase):
CALLBACK_NAME = 'log_plays'
CALLBACK_NEEDS_WHITELIST = True
TIME_FORMAT="%b %d %Y %H:%M:%S"
MSG_FORMAT="%(now)s - %(category)s - %(data)s\n\n"
TIME_FORMAT = "%b %d %Y %H:%M:%S"
MSG_FORMAT = "%(now)s - %(category)s - %(data)s\n\n"
def __init__(self):

View File

@@ -160,10 +160,10 @@ class PlainTextSocketAppender(object):
try:
import ssl
HAS_SSL=True
HAS_SSL = True
except ImportError: # for systems without TLS support.
SocketAppender = PlainTextSocketAppender
HAS_SSL=False
HAS_SSL = False
else:
class TLSSocketAppender(PlainTextSocketAppender):
@@ -199,14 +199,14 @@ class CallbackModule(CallbackBase):
self._display.warning("Unable to import ssl module. Will send over port 80.")
if not HAS_CERTIFI:
self.disabled =True
self.disabled = True
self._display.warning('The `certifi` python module is not installed. '
'Disabling the Logentries callback plugin.')
'Disabling the Logentries callback plugin.')
if not HAS_FLATDICT:
self.disabled =True
self.disabled = True
self._display.warning('The `flatdict` python module is not installed. '
'Disabling the Logentries callback plugin.')
'Disabling the Logentries callback plugin.')
config_path = os.path.abspath(os.path.dirname(__file__))
config = configparser.ConfigParser()

View File

@@ -33,6 +33,7 @@ except ImportError:
from ansible.plugins.callback import CallbackBase
class CallbackModule(CallbackBase):
"""
ansible logstash callback plugin
@@ -69,9 +70,9 @@ class CallbackModule(CallbackBase):
if not HAS_LOGSTASH:
self.disabled = True
self._display.warning("The required python-logstash is not installed. "
"pip install python-logstash")
"pip install python-logstash")
else:
self.logger = logging.getLogger('python-logstash-logger')
self.logger = logging.getLogger('python-logstash-logger')
self.logger.setLevel(logging.DEBUG)
self.handler = logstash.TCPLogstashHandler(
@@ -95,7 +96,7 @@ class CallbackModule(CallbackBase):
'ansible_type': "start",
'ansible_playbook': self.playbook,
}
self.logger.info("ansible start", extra = data)
self.logger.info("ansible start", extra=data)
def v2_playbook_on_stats(self, stats):
summarize_stat = {}
@@ -115,7 +116,7 @@ class CallbackModule(CallbackBase):
'ansible_playbook': self.playbook,
'ansible_result': json.dumps(summarize_stat),
}
self.logger.info("ansible stats", extra = data)
self.logger.info("ansible stats", extra=data)
def v2_runner_on_ok(self, result, **kwargs):
data = {
@@ -128,7 +129,7 @@ class CallbackModule(CallbackBase):
'ansible_task': result._task,
'ansible_result': self._dump_results(result._result)
}
self.logger.info("ansible ok", extra = data)
self.logger.info("ansible ok", extra=data)
def v2_runner_on_skipped(self, result, **kwargs):
data = {
@@ -140,7 +141,7 @@ class CallbackModule(CallbackBase):
'ansible_task': result._task,
'ansible_host': result._host.name
}
self.logger.info("ansible skipped", extra = data)
self.logger.info("ansible skipped", extra=data)
def v2_playbook_on_import_for_host(self, result, imported_file):
data = {
@@ -152,7 +153,7 @@ class CallbackModule(CallbackBase):
'ansible_host': result._host.name,
'imported_file': imported_file
}
self.logger.info("ansible import", extra = data)
self.logger.info("ansible import", extra=data)
def v2_playbook_on_not_import_for_host(self, result, missing_file):
data = {
@@ -164,7 +165,7 @@ class CallbackModule(CallbackBase):
'ansible_host': result._host.name,
'missing_file': missing_file
}
self.logger.info("ansible import", extra = data)
self.logger.info("ansible import", extra=data)
def v2_runner_on_failed(self, result, **kwargs):
data = {
@@ -178,7 +179,7 @@ class CallbackModule(CallbackBase):
'ansible_result': self._dump_results(result._result)
}
self.errors += 1
self.logger.error("ansible failed", extra = data)
self.logger.error("ansible failed", extra=data)
def v2_runner_on_unreachable(self, result, **kwargs):
data = {
@@ -191,7 +192,7 @@ class CallbackModule(CallbackBase):
'ansible_task': result._task,
'ansible_result': self._dump_results(result._result)
}
self.logger.error("ansbile unreachable", extra = data)
self.logger.error("ansbile unreachable", extra=data)
def v2_runner_on_async_failed(self, result, **kwargs):
data = {
@@ -205,4 +206,4 @@ class CallbackModule(CallbackBase):
'ansible_result': self._dump_results(result._result)
}
self.errors += 1
self.logger.error("ansible async", extra = data)
self.logger.error("ansible async", extra=data)

View File

@@ -32,11 +32,11 @@ from ansible.plugins.callback import CallbackBase
def mail(subject='Ansible error mail', sender=None, to=None, cc=None, bcc=None, body=None, smtphost=None):
if sender is None:
sender='<root>'
sender = '<root>'
if to is None:
to='root'
to = 'root'
if smtphost is None:
smtphost=os.getenv('SMTPHOST', 'localhost')
smtphost = os.getenv('SMTPHOST', 'localhost')
if body is None:
body = subject

View File

@@ -38,9 +38,9 @@ class CallbackModule(CallbackBase):
''' output the result of a command run '''
buf = "%s | %s | rc=%s >>\n" % (host, caption, result.get('rc', -1))
buf += result.get('stdout','')
buf += result.get('stderr','')
buf += result.get('msg','')
buf += result.get('stdout', '')
buf += result.get('stderr', '')
buf += result.get('msg', '')
return buf + "\n"

View File

@@ -34,10 +34,10 @@ class CallbackModule(CallbackBase):
CALLBACK_TYPE = 'stdout'
CALLBACK_NAME = 'oneline'
def _command_generic_msg(self, hostname, result, caption):
stdout = result.get('stdout','').replace('\n', '\\n').replace('\r', '\\r')
def _command_generic_msg(self, hostname, result, caption):
stdout = result.get('stdout', '').replace('\n', '\\n').replace('\r', '\\r')
if 'stderr' in result and result['stderr']:
stderr = result.get('stderr','').replace('\n', '\\n').replace('\r', '\\r')
stderr = result.get('stderr', '').replace('\n', '\\n').replace('\r', '\\r')
return "%s | %s | rc=%s | (stdout) %s (stderr) %s" % (hostname, caption, result.get('rc', -1), stdout, stderr)
else:
return "%s | %s | rc=%s | (stdout) %s" % (hostname, caption, result.get('rc', -1), stdout)
@@ -49,26 +49,25 @@ class CallbackModule(CallbackBase):
error = result._result['exception'].strip().split('\n')[-1]
msg = "An exception occurred during task execution. To see the full traceback, use -vvv. The error was: %s" % error
else:
msg = "An exception occurred during task execution. The full traceback is:\n" + result._result['exception'].replace('\n','')
msg = "An exception occurred during task execution. The full traceback is:\n" + result._result['exception'].replace('\n', '')
if result._task.action in C.MODULE_NO_JSON and 'module_stderr' not in result._result:
self._display.display(self._command_generic_msg(result._host.get_name(), result._result,'FAILED'), color=C.COLOR_ERROR)
self._display.display(self._command_generic_msg(result._host.get_name(), result._result, 'FAILED'), color=C.COLOR_ERROR)
else:
self._display.display(msg, color=C.COLOR_ERROR)
self._display.display("%s | FAILED! => %s" % (result._host.get_name(), self._dump_results(result._result, indent=0).replace('\n','')),
self._display.display("%s | FAILED! => %s" % (result._host.get_name(), self._dump_results(result._result, indent=0).replace('\n', '')),
color=C.COLOR_ERROR)
def v2_runner_on_ok(self, result):
if result._task.action in C.MODULE_NO_JSON:
self._display.display(self._command_generic_msg(result._host.get_name(), result._result,'SUCCESS'), color=C.COLOR_OK)
self._display.display(self._command_generic_msg(result._host.get_name(), result._result, 'SUCCESS'), color=C.COLOR_OK)
else:
self._display.display("%s | SUCCESS => %s" % (result._host.get_name(), self._dump_results(result._result, indent=0).replace('\n','')),
self._display.display("%s | SUCCESS => %s" % (result._host.get_name(), self._dump_results(result._result, indent=0).replace('\n', '')),
color=C.COLOR_OK)
def v2_runner_on_unreachable(self, result):
self._display.display("%s | UNREACHABLE!: %s" % (result._host.get_name(), result._result.get('msg','')), color=C.COLOR_UNREACHABLE)
self._display.display("%s | UNREACHABLE!: %s" % (result._host.get_name(), result._result.get('msg', '')), color=C.COLOR_UNREACHABLE)
def v2_runner_on_skipped(self, result):
self._display.display("%s | SKIPPED" % (result._host.get_name()), color=C.COLOR_SKIP)

View File

@@ -25,11 +25,12 @@ import os
from ansible.plugins.callback import CallbackBase
FAILED_VOICE="Zarvox"
REGULAR_VOICE="Trinoids"
HAPPY_VOICE="Cellos"
LASER_VOICE="Princess"
SAY_CMD="/usr/bin/say"
FAILED_VOICE = "Zarvox"
REGULAR_VOICE = "Trinoids"
HAPPY_VOICE = "Cellos"
LASER_VOICE = "Princess"
SAY_CMD = "/usr/bin/say"
class CallbackModule(CallbackBase):
"""
@@ -48,7 +49,7 @@ class CallbackModule(CallbackBase):
# ansible will not call any callback if disabled is set to True
if not os.path.exists(SAY_CMD):
self.disabled = True
self._display.warning("%s does not exist, plugin %s disabled" % (SAY_CMD, os.path.basename(__file__)) )
self._display.warning("%s does not exist, plugin %s disabled" % (SAY_CMD, os.path.basename(__file__)))
def say(self, msg, voice):
subprocess.call([SAY_CMD, msg, "--voice=%s" % (voice)])

View File

@@ -37,7 +37,9 @@ t0 = tn = time.time()
def secondsToStr(t):
# http://bytes.com/topic/python/answers/635958-handy-short-cut-formatting-elapsed-time-floating-point-seconds
rediv = lambda ll, b: list(divmod(ll[0], b)) + ll[1:]
def rediv(ll, b):
return list(divmod(ll[0], b)) + ll[1:]
return "%d:%02d:%02d.%03d" % tuple(reduce(rediv, [[t * 1000, ], 1000, 60, 60]))
@@ -104,7 +106,7 @@ class CallbackModule(CallbackBase):
self.current = task._uuid
self.stats[self.current] = {'time': time.time(), 'name': task.get_name()}
if self._display.verbosity >= 2:
self.stats[self.current][ 'path'] = task.get_path()
self.stats[self.current]['path'] = task.get_path()
def v2_playbook_on_task_start(self, task, is_conditional):
self._record_task(task)
@@ -127,7 +129,7 @@ class CallbackModule(CallbackBase):
if self.sort_order != 'none':
results = sorted(
self.stats.items(),
key=lambda x:x[1]['time'],
key=lambda x: x[1]['time'],
reverse=self.sort_order,
)
@@ -136,7 +138,7 @@ class CallbackModule(CallbackBase):
# Print the timings
for uuid, result in results:
msg=u"{0:-<{2}}{1:->9}".format(result['name'] + u' ',u' {0:.02f}s'.format(result['time']), self._display.columns - 9)
msg = u"{0:-<{2}}{1:->9}".format(result['name'] + u' ', u' {0:.02f}s'.format(result['time']), self._display.columns - 9)
if 'path' in result:
msg += u"\n{0:-<{1}}".format(result['path'] + u' ', self._display.columns)
self._display.display(msg)

View File

@@ -106,7 +106,7 @@ class CallbackModule(CallbackBase):
lines = text.splitlines()
result_lines = []
for l in lines:
result_lines.append("{}{}".format(' '*indent_level, l))
result_lines.append("{}{}".format(' ' * indent_level, l))
return '\n'.join(result_lines)
def _print_diff(self, diff, indent_level):
@@ -121,7 +121,7 @@ class CallbackModule(CallbackBase):
diff = dict_diff(diff['before'], diff['after'])
if diff:
diff = colorize(str(diff), 'changed')
print(self._indent_text(diff, indent_level+4))
print(self._indent_text(diff, indent_level + 4))
def _print_host_or_item(self, host_or_item, changed, msg, diff, is_host, error, stdout, stderr):
if is_host:
@@ -144,7 +144,7 @@ class CallbackModule(CallbackBase):
msg = colorize(msg, color)
line_length = 120
spaces = ' ' * (40-len(name)-indent_level)
spaces = ' ' * (40 - len(name) - indent_level)
line = "{} * {}{}- {}".format(' ' * indent_level, name, spaces, change_string)
if len(msg) < 50:
@@ -152,16 +152,16 @@ class CallbackModule(CallbackBase):
print("{} {}---------".format(line, '-' * (line_length - len(line))))
else:
print("{} {}".format(line, '-' * (line_length - len(line))))
print(self._indent_text(msg, indent_level+4))
print(self._indent_text(msg, indent_level + 4))
if diff is not None:
self._print_diff(diff, indent_level)
if stdout is not None:
stdout = colorize(stdout, 'failed')
print(self._indent_text(stdout, indent_level+4))
print(self._indent_text(stdout, indent_level + 4))
if stderr is not None:
stderr = colorize(stderr, 'failed')
print(self._indent_text(stderr, indent_level+4))
print(self._indent_text(stderr, indent_level + 4))
def v2_playbook_on_play_start(self, play):
"""Run on start of the play."""
@@ -236,7 +236,7 @@ class CallbackModule(CallbackBase):
self.last_skipped = False
line_length = 120
spaces = ' ' * (31-len(result._host.name)-4)
spaces = ' ' * (31 - len(result._host.name) - 4)
line = " * {}{}- {}".format(colorize(result._host.name, 'not_so_bold'),
spaces,
@@ -255,4 +255,3 @@ class CallbackModule(CallbackBase):
v2_playbook_on_handler_task_start = v2_playbook_on_task_start
v2_runner_on_failed = v2_runner_on_ok
v2_runner_on_unreachable = v2_runner_on_ok

View File

@@ -21,6 +21,7 @@ __metaclass__ = type
from ansible.plugins.callback.default import CallbackModule as CallbackModule_default
class CallbackModule(CallbackModule_default):
'''

View File

@@ -68,7 +68,6 @@ class CallbackModule(CallbackBase):
else:
self._options = None
super(CallbackModule, self).__init__(display=display)
if not HAS_PRETTYTABLE:

View File

@@ -12,6 +12,7 @@ import socket
from ansible.plugins.callback import CallbackBase
class CallbackModule(CallbackBase):
"""
logs ansible-playbook and ansible runs to a syslog server in json format
@@ -33,35 +34,33 @@ class CallbackModule(CallbackBase):
super(CallbackModule, self).__init__()
self.logger = logging.getLogger('ansible logger')
self.logger = logging.getLogger('ansible logger')
self.logger.setLevel(logging.DEBUG)
self.handler = logging.handlers.SysLogHandler(
address = (os.getenv('SYSLOG_SERVER','localhost'),
int(os.getenv('SYSLOG_PORT',514))),
facility= os.getenv('SYSLOG_FACILITY',logging.handlers.SysLogHandler.LOG_USER)
address=(os.getenv('SYSLOG_SERVER', 'localhost'), int(os.getenv('SYSLOG_PORT', 514))),
facility=os.getenv('SYSLOG_FACILITY', logging.handlers.SysLogHandler.LOG_USER)
)
self.logger.addHandler(self.handler)
self.hostname = socket.gethostname()
def runner_on_failed(self, host, res, ignore_errors=False):
self.logger.error('%s ansible-command: task execution FAILED; host: %s; message: %s' % (self.hostname,host,self._dump_results(res)))
self.logger.error('%s ansible-command: task execution FAILED; host: %s; message: %s' % (self.hostname, host, self._dump_results(res)))
def runner_on_ok(self, host, res):
self.logger.info('%s ansible-command: task execution OK; host: %s; message: %s' % (self.hostname,host,self._dump_results(res)))
self.logger.info('%s ansible-command: task execution OK; host: %s; message: %s' % (self.hostname, host, self._dump_results(res)))
def runner_on_skipped(self, host, item=None):
self.logger.info('%s ansible-command: task execution SKIPPED; host: %s; message: %s' % (self.hostname,host, 'skipped'))
self.logger.info('%s ansible-command: task execution SKIPPED; host: %s; message: %s' % (self.hostname, host, 'skipped'))
def runner_on_unreachable(self, host, res):
self.logger.error('%s ansible-command: task execution UNREACHABLE; host: %s; message: %s' % (self.hostname,host,self._dump_results(res)))
self.logger.error('%s ansible-command: task execution UNREACHABLE; host: %s; message: %s' % (self.hostname, host, self._dump_results(res)))
def runner_on_async_failed(self, host, res, jid):
self.logger.error('%s ansible-command: task execution FAILED; host: %s; message: %s' % (self.hostname,host,self._dump_results(res)))
self.logger.error('%s ansible-command: task execution FAILED; host: %s; message: %s' % (self.hostname, host, self._dump_results(res)))
def playbook_on_import_for_host(self, host, imported_file):
self.logger.info('%s ansible-command: playbook IMPORTED; host: %s; message: imported file %s' % (self.hostname,host,imported_file))
self.logger.info('%s ansible-command: playbook IMPORTED; host: %s; message: imported file %s' % (self.hostname, host, imported_file))
def playbook_on_not_import_for_host(self, host, missing_file):
self.logger.info('%s ansible-command: playbook NOT IMPORTED; host: %s; message: missing file %s' % (self.hostname,host,missing_file))
self.logger.info('%s ansible-command: playbook NOT IMPORTED; host: %s; message: missing file %s' % (self.hostname, host, missing_file))

View File

@@ -59,8 +59,8 @@ class ConnectionBase(with_metaclass(ABCMeta, object)):
'''
has_pipelining = False
has_native_async = False # eg, winrm
always_pipeline_modules = False # eg, winrm
has_native_async = False # eg, winrm
always_pipeline_modules = False # eg, winrm
become_methods = C.BECOME_METHODS
# When running over this connection type, prefer modules written in a certain language
# as discovered by the specified file extension. An empty string as the

View File

@@ -44,7 +44,7 @@ except ImportError:
# ((1400-8)/4)*3) = 1044
# which leaves room for the TCP/IP header. We set this to a
# multiple of the value to speed up file reads.
CHUNK_SIZE=1044*20
CHUNK_SIZE = 1044 * 20
class Connection(ConnectionBase):
@@ -73,7 +73,7 @@ class Connection(ConnectionBase):
host=self._play_context.remote_addr)
while tries > 0:
try:
self.conn.connect((self._play_context.remote_addr,self._play_context.accelerate_port))
self.conn.connect((self._play_context.remote_addr, self._play_context.accelerate_port))
break
except socket.error:
display.vvvv("connection to %s failed, retrying..." % self._play_context.remote_addr, host=self._play_context.remote_addr)
@@ -107,11 +107,11 @@ class Connection(ConnectionBase):
sock.close()
def send_data(self, data):
packed_len = struct.pack('!Q',len(data))
packed_len = struct.pack('!Q', len(data))
return self.conn.sendall(packed_len + data)
def recv_data(self):
header_len = 8 # size of a packed unsigned long long
header_len = 8 # size of a packed unsigned long long
data = b""
try:
display.vvvv("in recv_data(), waiting for the header", host=self._play_context.remote_addr)
@@ -122,7 +122,7 @@ class Connection(ConnectionBase):
return None
data += d
display.vvvv("got the header, unpacking", host=self._play_context.remote_addr)
data_len = struct.unpack('!Q',data[:header_len])[0]
data_len = struct.unpack('!Q', data[:header_len])[0]
data = data[header_len:]
display.vvvv("data received so far (expecting %d): %d" % (data_len, len(data)), host=self._play_context.remote_addr)
while len(data) < data_len:
@@ -252,7 +252,7 @@ class Connection(ConnectionBase):
response = keyczar_decrypt(self.key, response)
response = json.loads(response)
if response.get('failed',False):
if response.get('failed', False):
raise AnsibleError("failed to put the file in the requested location")
finally:
fd.close()
@@ -263,7 +263,7 @@ class Connection(ConnectionBase):
response = keyczar_decrypt(self.key, response)
response = json.loads(response)
if response.get('failed',False):
if response.get('failed', False):
raise AnsibleError("failed to put the file in the requested location")
def fetch_file(self, in_path, out_path):

View File

@@ -96,7 +96,7 @@ class Connection(ConnectionBase):
display.vvv("EXEC %s" % (local_cmd), host=self.chroot)
local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]
p = subprocess.Popen(local_cmd, shell=False, stdin=stdin,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return p

View File

@@ -235,7 +235,7 @@ class Connection(ConnectionBase):
with open(to_bytes(in_path, errors='surrogate_or_strict'), 'rb') as in_file:
try:
p = subprocess.Popen(args, stdin=in_file,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
except OSError:
raise AnsibleError("docker connection requires dd command in the container to put files")
stdout, stderr = p.communicate()
@@ -257,7 +257,7 @@ class Connection(ConnectionBase):
args = [to_bytes(i, errors='surrogate_or_strict') for i in args]
p = subprocess.Popen(args, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.communicate()
# Rename if needed

View File

@@ -43,6 +43,7 @@ except ImportError:
from ansible.utils.display import Display
display = Display()
class Connection(object):
''' Func-based connections '''

View File

@@ -65,4 +65,3 @@ class Connection(Jail):
raise AnsibleError(u"iocage returned an error: {}".format(stdout))
return stdout.strip('\n')

View File

@@ -56,7 +56,7 @@ class Connection(ConnectionBase):
super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs)
self.jail = self._play_context.remote_addr
if self.modified_jailname_key in kwargs :
if self.modified_jailname_key in kwargs:
self.jail = kwargs[self.modified_jailname_key]
if os.geteuid() != 0:
@@ -122,7 +122,7 @@ class Connection(ConnectionBase):
display.vvv("EXEC %s" % (local_cmd,), host=self.jail)
local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]
p = subprocess.Popen(local_cmd, shell=False, stdin=stdin,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return p

View File

@@ -97,7 +97,7 @@ class Connection(ConnectionBase):
display.vvv("EXEC %s" % (local_cmd,), host=self.lxc)
local_cmd = [to_bytes(i, errors='surrogate_or_strict') for i in local_cmd]
p = subprocess.Popen(local_cmd, shell=False, stdin=stdin,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return p

View File

@@ -90,7 +90,7 @@ class Connection(ConnectionBase):
p = subprocess.Popen(
cmd,
shell=isinstance(cmd, (text_type, binary_type)),
executable=executable, #cwd=...
executable=executable, # cwd=...
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,

View File

@@ -68,7 +68,7 @@ class Connection(ConnectionBase):
raise errors.AnsibleError("%s is not running" % self.container_name)
def _communicate(self, pid, in_data, stdin, stdout, stderr):
buf = { stdout: [], stderr: [] }
buf = {stdout: [], stderr: []}
read_fds = [stdout, stderr]
if in_data:
write_fds = [stdin]
@@ -109,7 +109,7 @@ class Connection(ConnectionBase):
read_stdout, write_stdout = None, None
read_stderr, write_stderr = None, None
read_stdin, write_stdin = None, None
read_stdin, write_stdin = None, None
try:
read_stdout, write_stdout = os.pipe()

View File

@@ -52,7 +52,7 @@ except ImportError:
display = Display()
AUTHENTICITY_MSG="""
AUTHENTICITY_MSG = """
paramiko: The authenticity of host '%s' can't be established.
The %s key fingerprint is %s.
Are you sure you want to continue connecting (yes/no)?
@@ -62,12 +62,12 @@ Are you sure you want to continue connecting (yes/no)?
SETTINGS_REGEX = re.compile(r'(\w+)(?:\s*=\s*|\s+)(.+)')
# prevent paramiko warning noise -- see http://stackoverflow.com/questions/3920502/
HAVE_PARAMIKO=False
HAVE_PARAMIKO = False
with warnings.catch_warnings():
warnings.simplefilter("ignore")
try:
import paramiko
HAVE_PARAMIKO=True
HAVE_PARAMIKO = True
logging.getLogger("paramiko").setLevel(logging.WARNING)
except ImportError:
pass
@@ -109,7 +109,7 @@ class MyAddPolicy(object):
self.connection.connection_unlock()
if inp not in ['yes','y','']:
if inp not in ['yes', 'y', '']:
raise AnsibleError("host connection rejected by user")
key._added_by_ansible_this_time = True
@@ -213,11 +213,11 @@ class Connection(ConnectionBase):
if C.HOST_KEY_CHECKING:
for ssh_known_hosts in ("/etc/ssh/ssh_known_hosts", "/etc/openssh/ssh_known_hosts"):
try:
#TODO: check if we need to look at several possible locations, possible for loop
# TODO: check if we need to look at several possible locations, possible for loop
ssh.load_system_host_keys(ssh_known_hosts)
break
except IOError:
pass # file was not found, but not required to function
pass # file was not found, but not required to function
ssh.load_system_host_keys()
sock_kwarg = self._parse_proxy_command(port)
@@ -305,10 +305,10 @@ class Connection(ConnectionBase):
display.debug("chunk is: %s" % chunk)
if not chunk:
if b'unknown user' in become_output:
raise AnsibleError( 'user %s does not exist' % self._play_context.become_user)
raise AnsibleError('user %s does not exist' % self._play_context.become_user)
else:
break
#raise AnsibleError('ssh connection closed waiting for password prompt')
# raise AnsibleError('ssh connection closed waiting for password prompt')
become_output += chunk
# need to check every line because we might get lectured
@@ -441,7 +441,7 @@ class Connection(ConnectionBase):
# (This doesn't acquire the connection lock because it needs
# to exclude only other known_hosts writers, not connections
# that are starting up.)
lockfile = self.keyfile.replace("known_hosts",".known_hosts.lock")
lockfile = self.keyfile.replace("known_hosts", ".known_hosts.lock")
dirname = os.path.dirname(self.keyfile)
makedirs_safe(dirname)
@@ -457,7 +457,7 @@ class Connection(ConnectionBase):
# gather information about the current key file, so
# we can ensure the new file has the correct mode/owner
key_dir = os.path.dirname(self.keyfile)
key_dir = os.path.dirname(self.keyfile)
if os.path.exists(self.keyfile):
key_stat = os.stat(self.keyfile)
mode = key_stat.st_mode

View File

@@ -135,6 +135,7 @@ class AnsibleControlPersistBrokenPipeError(AnsibleError):
''' ControlPersist broken pipe '''
pass
def _ssh_retry(func):
"""
Decorator to retry ssh/scp/sftp in the case of a connection failure
@@ -365,12 +366,14 @@ class Connection(ConnectionBase):
user = self._play_context.remote_user
if user:
self._add_args(b_command,
(b"-o", b"User=" + to_bytes(self._play_context.remote_user, errors='surrogate_or_strict')),
self._add_args(
b_command,
(b"-o", b"User=" + to_bytes(self._play_context.remote_user, errors='surrogate_or_strict')),
u"ANSIBLE_REMOTE_USER/remote_user/ansible_user/user/-u set"
)
self._add_args(b_command,
self._add_args(
b_command,
(b"-o", b"ConnectTimeout=" + to_bytes(self._play_context.timeout, errors='surrogate_or_strict', nonstring='simplerepr')),
u"ANSIBLE_TIMEOUT/timeout set"
)
@@ -459,7 +462,7 @@ class Connection(ConnectionBase):
display_line = to_text(b_line).rstrip('\r\n')
suppress_output = False
#display.debug("Examining line (source=%s, state=%s): '%s'" % (source, state, display_line))
# display.debug("Examining line (source=%s, state=%s): '%s'" % (source, state, display_line))
if self._play_context.prompt and self.check_password_prompt(b_line):
display.debug("become_prompt: (source=%s, state=%s): '%s'" % (source, state, display_line))
self._flags['become_prompt'] = True
@@ -594,7 +597,7 @@ class Connection(ConnectionBase):
for fd in (p.stdout, p.stderr):
fcntl.fcntl(fd, fcntl.F_SETFL, fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK)
### TODO: bcoca would like to use SelectSelector() when open
# TODO: bcoca would like to use SelectSelector() when open
# filehandles is low, then switch to more efficient ones when higher.
# select is faster when filehandles is low.
selector = selectors.DefaultSelector()
@@ -839,8 +842,8 @@ class Connection(ConnectionBase):
if returncode == 255:
raise AnsibleConnectionFailure("Failed to connect to the host via %s: %s" % (method, to_native(stderr)))
else:
raise AnsibleError("failed to transfer file to {0} {1}:\n{2}\n{3}"\
.format(to_native(in_path), to_native(out_path), to_native(stdout), to_native(stderr)))
raise AnsibleError("failed to transfer file to %s %s:\n%s\n%s" %
(to_native(in_path), to_native(out_path), to_native(stdout), to_native(stderr)))
#
# Main public methods
@@ -852,7 +855,6 @@ class Connection(ConnectionBase):
display.vvv(u"ESTABLISH SSH CONNECTION FOR USER: {0}".format(self._play_context.remote_user), host=self._play_context.remote_addr)
# we can only use tty when we are not pipelining the modules. piping
# data into /usr/bin/python inside a tty automatically invokes the
# python interactive-mode but the modules are not compatible with the

View File

@@ -74,15 +74,15 @@ class Connection(ConnectionBase):
become_methods = ['runas']
allow_executable = False
def __init__(self, *args, **kwargs):
def __init__(self, *args, **kwargs):
self.has_pipelining = True
self.has_pipelining = True
self.always_pipeline_modules = True
self.has_native_async = True
self.protocol = None
self.shell_id = None
self.delegate = None
self._shell_type = 'powershell'
self.protocol = None
self.shell_id = None
self.delegate = None
self._shell_type = 'powershell'
# FUTURE: Add runas support
super(Connection, self).__init__(*args, **kwargs)
@@ -109,13 +109,13 @@ class Connection(ConnectionBase):
self._become_user = self._play_context.become_user
self._become_pass = self._play_context.become_pass
self._kinit_cmd = hostvars.get('ansible_winrm_kinit_cmd', 'kinit')
self._kinit_cmd = hostvars.get('ansible_winrm_kinit_cmd', 'kinit')
if hasattr(winrm, 'FEATURE_SUPPORTED_AUTHTYPES'):
self._winrm_supported_authtypes = set(winrm.FEATURE_SUPPORTED_AUTHTYPES)
else:
# for legacy versions of pywinrm, use the values we know are supported
self._winrm_supported_authtypes = set(['plaintext','ssl','kerberos'])
self._winrm_supported_authtypes = set(['plaintext', 'ssl', 'kerberos'])
# TODO: figure out what we want to do with auto-transport selection in the face of NTLM/Kerb/CredSSP/Cert/Basic
transport_selector = 'ssl' if self._winrm_scheme == 'https' else 'plaintext'
@@ -191,7 +191,7 @@ class Connection(ConnectionBase):
Establish a WinRM connection over HTTP/HTTPS.
'''
display.vvv("ESTABLISH WINRM CONNECTION FOR USER: %s on PORT %s TO %s" %
(self._winrm_user, self._winrm_port, self._winrm_host), host=self._winrm_host)
(self._winrm_user, self._winrm_port, self._winrm_host), host=self._winrm_host)
netloc = '%s:%d' % (self._winrm_host, self._winrm_port)
endpoint = urlunsplit((self._winrm_scheme, netloc, self._winrm_path, '', ''))
errors = []
@@ -320,7 +320,7 @@ class Connection(ConnectionBase):
payload_bytes = to_bytes(payload)
byte_count = len(payload_bytes)
for i in range(0, byte_count, buffer_size):
yield payload_bytes[i:i+buffer_size], i+buffer_size >= byte_count
yield payload_bytes[i:i + buffer_size], i + buffer_size >= byte_count
def exec_command(self, cmd, in_data=None, sudoable=True):
super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)
@@ -349,7 +349,6 @@ class Connection(ConnectionBase):
return (result.status_code, result.std_out, result.std_err)
def exec_command_old(self, cmd, in_data=None, sudoable=True):
super(Connection, self).exec_command(cmd, in_data=in_data, sudoable=sudoable)
cmd_parts = shlex.split(to_bytes(cmd), posix=False)
@@ -406,7 +405,7 @@ class Connection(ConnectionBase):
in_size = os.path.getsize(to_bytes(in_path, errors='surrogate_or_strict'))
offset = 0
with open(to_bytes(in_path, errors='surrogate_or_strict'), 'rb') as in_file:
for out_data in iter((lambda:in_file.read(buffer_size)), ''):
for out_data in iter((lambda: in_file.read(buffer_size)), ''):
offset += len(out_data)
self._display.vvvvv('WINRM PUT "%s" to "%s" (offset=%d size=%d)' % (in_path, out_path, offset, len(out_data)), host=self._winrm_host)
# yes, we're double-encoding over the wire in this case- we want to ensure that the data shipped to the end PS pipeline is still b64-encoded

View File

@@ -71,8 +71,8 @@ class Connection(ConnectionBase):
def list_zones(self):
process = subprocess.Popen([self.zoneadm_cmd, 'list', '-ip'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
zones = []
for l in process.stdout.readlines():
@@ -84,13 +84,13 @@ class Connection(ConnectionBase):
return zones
def get_zone_path(self):
#solaris10vm# zoneadm -z cswbuild list -p
#-:cswbuild:installed:/zones/cswbuild:479f3c4b-d0c6-e97b-cd04-fd58f2c0238e:native:shared
# solaris10vm# zoneadm -z cswbuild list -p
# -:cswbuild:installed:/zones/cswbuild:479f3c4b-d0c6-e97b-cd04-fd58f2c0238e:native:shared
process = subprocess.Popen([self.zoneadm_cmd, '-z', to_bytes(self.zone), 'list', '-p'],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
#stdout, stderr = p.communicate()
# stdout, stderr = p.communicate()
path = process.stdout.readlines()[0].split(':')[3]
return path + '/root'
@@ -109,7 +109,7 @@ class Connection(ConnectionBase):
compared to exec_command() it looses some niceties like being able to
return the process's exit code immediately.
'''
# Note: zlogin invokes a shell (just like ssh does) so we do not pass
# NOTE: zlogin invokes a shell (just like ssh does) so we do not pass
# this through /bin/sh -c here. Instead it goes through the shell
# that zlogin selects.
local_cmd = [self.zlogin_cmd, self.zone, cmd]
@@ -117,7 +117,7 @@ class Connection(ConnectionBase):
display.vvv("EXEC %s" % (local_cmd), host=self.zone)
p = subprocess.Popen(local_cmd, shell=False, stdin=stdin,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return p

View File

@@ -1,5 +1,3 @@
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

View File

@@ -72,20 +72,24 @@ class AnsibleJSONEncoder(json.JSONEncoder):
else:
return super(AnsibleJSONEncoder, self).default(o)
def to_yaml(a, *args, **kw):
'''Make verbose, human readable yaml'''
transformed = yaml.dump(a, Dumper=AnsibleDumper, allow_unicode=True, **kw)
return to_text(transformed)
def to_nice_yaml(a, indent=4, *args, **kw):
'''Make verbose, human readable yaml'''
transformed = yaml.dump(a, Dumper=AnsibleDumper, indent=indent, allow_unicode=True, default_flow_style=False, **kw)
return to_text(transformed)
def to_json(a, *args, **kw):
''' Convert the value to JSON '''
return json.dumps(a, cls=AnsibleJSONEncoder, *args, **kw)
def to_nice_json(a, indent=4, *args, **kw):
'''Make verbose, human readable JSON'''
# python-2.6's json encoder is buggy (can't encode hostvars)
@@ -109,6 +113,7 @@ def to_nice_json(a, indent=4, *args, **kw):
# Fallback to the to_json filter
return to_json(a, *args, **kw)
def to_bool(a):
''' return a bool for the arg '''
if a is None or isinstance(a, bool):
@@ -119,11 +124,12 @@ def to_bool(a):
return True
return False
def to_datetime(string, format="%Y-%d-%m %H:%M:%S"):
return datetime.strptime(string, format)
def strftime(string_format, second = None):
def strftime(string_format, second=None):
''' return a date string using string. See https://docs.python.org/2/library/time.html#time.strftime for format '''
if second is not None:
try:
@@ -132,13 +138,16 @@ def strftime(string_format, second = None):
raise errors.AnsibleFilterError('Invalid value for epoch value (%s)' % second)
return time.strftime(string_format, time.localtime(second))
def quote(a):
''' return its argument quoted for shell usage '''
return shlex_quote(a)
def fileglob(pathname):
''' return list of matched regular files for glob '''
return [ g for g in glob.glob(pathname) if os.path.isfile(g) ]
return [g for g in glob.glob(pathname) if os.path.isfile(g)]
def regex_replace(value='', pattern='', replacement='', ignorecase=False):
''' Perform a `re.sub` returning a string '''
@@ -152,6 +161,7 @@ def regex_replace(value='', pattern='', replacement='', ignorecase=False):
_re = re.compile(pattern, flags=flags)
return _re.sub(replacement, value)
def regex_findall(value, regex, multiline=False, ignorecase=False):
''' Perform re.findall and return the list of matches '''
flags = 0
@@ -161,6 +171,7 @@ def regex_findall(value, regex, multiline=False, ignorecase=False):
flags |= re.M
return re.findall(regex, value, flags)
def regex_search(value, regex, *args, **kwargs):
''' Perform re.search and return the list of matches or a backref '''
@@ -191,6 +202,7 @@ def regex_search(value, regex, *args, **kwargs):
items.append(match.group(item))
return items
def ternary(value, true_val, false_val):
''' value ? true_val : false_val '''
if value:
@@ -199,16 +211,17 @@ def ternary(value, true_val, false_val):
return false_val
def regex_escape(string):
'''Escape all regular expressions special characters from STRING.'''
return re.escape(string)
def from_yaml(data):
if isinstance(data, string_types):
return yaml.safe_load(data)
return data
@environmentfilter
def rand(environment, end, start=None, step=None, seed=None):
if seed is None:
@@ -228,6 +241,7 @@ def rand(environment, end, start=None, step=None, seed=None):
else:
raise errors.AnsibleFilterError('random can only be used on sequences and integers')
def randomize_list(mylist, seed=None):
try:
mylist = list(mylist)
@@ -240,9 +254,10 @@ def randomize_list(mylist, seed=None):
pass
return mylist
def get_hash(data, hashtype='sha1'):
try: # see if hash is supported
try: # see if hash is supported
h = hashlib.new(hashtype)
except:
return None
@@ -250,14 +265,15 @@ def get_hash(data, hashtype='sha1'):
h.update(to_bytes(data, errors='surrogate_then_strict'))
return h.hexdigest()
def get_encrypted_password(password, hashtype='sha512', salt=None):
# TODO: find a way to construct dynamically from system
cryptmethod= {
'md5': '1',
cryptmethod = {
'md5': '1',
'blowfish': '2a',
'sha256': '5',
'sha512': '6',
'sha256': '5',
'sha512': '6',
}
if hashtype in cryptmethod:
@@ -273,7 +289,7 @@ def get_encrypted_password(password, hashtype='sha512', salt=None):
if not HAS_PASSLIB:
if sys.platform.startswith('darwin'):
raise errors.AnsibleFilterError('|password_hash requires the passlib python module to generate password hashes on Mac OS X/Darwin')
saltstring = "$%s$%s" % (cryptmethod[hashtype],salt)
saltstring = "$%s$%s" % (cryptmethod[hashtype], salt)
encrypted = crypt.crypt(password, saltstring)
else:
if hashtype == 'blowfish':
@@ -287,9 +303,11 @@ def get_encrypted_password(password, hashtype='sha512', salt=None):
return None
def to_uuid(string):
return str(uuid.uuid5(UUID_NAMESPACE_ANSIBLE, str(string)))
def mandatory(a):
from jinja2.runtime import Undefined
@@ -298,6 +316,7 @@ def mandatory(a):
raise errors.AnsibleFilterError('Mandatory variable not defined.')
return a
def combine(*terms, **kwargs):
recursive = kwargs.get('recursive', False)
if len(kwargs) > 1 or (len(kwargs) == 1 and 'recursive' not in kwargs):
@@ -312,6 +331,7 @@ def combine(*terms, **kwargs):
else:
return dict(itertools.chain(*map(iteritems, terms)))
def comment(text, style='plain', **kw):
# Predefined comment types
comment_styles = {
@@ -394,6 +414,7 @@ def comment(text, style='plain', **kw):
str_postfix,
str_end)
def extract(item, container, morekeys=None):
from jinja2.runtime import Undefined
@@ -410,6 +431,7 @@ def extract(item, container, morekeys=None):
return value
def failed(*a, **kw):
''' Test if task result yields failed '''
item = a[0]
@@ -422,26 +444,31 @@ def failed(*a, **kw):
else:
return False
def success(*a, **kw):
''' Test if task result yields success '''
return not failed(*a, **kw)
def changed(*a, **kw):
''' Test if task result yields changed '''
item = a[0]
if not isinstance(item, MutableMapping):
raise errors.AnsibleFilterError("|changed expects a dictionary")
if not 'changed' in item:
if 'changed' not in item:
changed = False
if ('results' in item # some modules return a 'results' key
and isinstance(item['results'], MutableSequence)
and isinstance(item['results'][0], MutableMapping)):
if (
'results' in item and # some modules return a 'results' key
isinstance(item['results'], MutableSequence) and
isinstance(item['results'][0], MutableMapping)
):
for result in item['results']:
changed = changed or result.get('changed', False)
else:
changed = item.get('changed', False)
return changed
def skipped(*a, **kw):
''' Test if task result yields skipped '''
item = a[0]
@@ -504,7 +531,7 @@ class FilterModule(object):
'to_nice_yaml': to_nice_yaml,
'from_yaml': from_yaml,
#date
# date
'to_datetime': to_datetime,
# path
@@ -567,18 +594,18 @@ class FilterModule(object):
'extract': extract,
# failure testing
'failed' : failed,
'failure' : failed,
'success' : success,
'succeeded' : success,
'failed': failed,
'failure': failed,
'success': success,
'succeeded': success,
# changed testing
'changed' : changed,
'change' : changed,
'changed': changed,
'change': changed,
# skip testing
'skipped' : skipped,
'skip' : skipped,
'skipped': skipped,
'skip': skipped,
# debug
'type_debug': lambda o: o.__class__.__name__,

View File

@@ -36,7 +36,6 @@ from ansible import errors
# ---- IP address and network query helpers ----
def _empty_ipaddr_query(v, vtype):
# We don't have any query to process, so just check what type the user
# expects, and return the IP address in a correct format
@@ -46,6 +45,7 @@ def _empty_ipaddr_query(v, vtype):
elif vtype == 'network':
return str(v)
def _6to4_query(v, vtype, value):
if v.version == 4:
@@ -76,6 +76,7 @@ def _6to4_query(v, vtype, value):
else:
return False
def _ip_query(v):
if v.size == 1:
return str(v.ip)
@@ -84,22 +85,27 @@ def _ip_query(v):
if v.ip != v.network or not v.broadcast:
return str(v.ip)
def _gateway_query(v):
if v.size > 1:
if v.ip != v.network:
return str(v.ip) + '/' + str(v.prefixlen)
def _bool_ipaddr_query(v):
if v:
return True
def _broadcast_query(v):
if v.size > 1:
return str(v.broadcast)
def _cidr_query(v):
return str(v)
def _cidr_lookup_query(v, iplist, value):
try:
if v in iplist:
@@ -107,6 +113,7 @@ def _cidr_lookup_query(v, iplist, value):
except:
return False
def _host_query(v):
if v.size == 1:
return str(v)
@@ -114,15 +121,18 @@ def _host_query(v):
if v.ip != v.network:
return str(v.ip) + '/' + str(v.prefixlen)
def _hostmask_query(v):
return str(v.hostmask)
def _int_query(v, vtype):
if vtype == 'address':
return int(v.ip)
elif vtype == 'network':
return str(int(v.ip)) + '/' + str(int(v.prefixlen))
def _ipv4_query(v, value):
if v.version == 6:
try:
@@ -132,12 +142,14 @@ def _ipv4_query(v, value):
else:
return value
def _ipv6_query(v, value):
if v.version == 4:
return str(v.ipv6())
else:
return value
def _link_local_query(v, value):
v_ip = netaddr.IPAddress(str(v.ip))
if v.version == 4:
@@ -148,34 +160,42 @@ def _link_local_query(v, value):
if ipaddr(str(v_ip), 'fe80::/10'):
return value
def _loopback_query(v, value):
v_ip = netaddr.IPAddress(str(v.ip))
if v_ip.is_loopback():
return value
def _multicast_query(v, value):
if v.is_multicast():
return value
def _net_query(v):
if v.size > 1:
if v.ip == v.network:
return str(v.network) + '/' + str(v.prefixlen)
def _netmask_query(v):
return str(v.netmask)
def _network_query(v):
if v.size > 1:
return str(v.network)
def _prefix_query(v):
return int(v.prefixlen)
def _private_query(v, value):
if v.is_private():
return value
def _public_query(v, value):
v_ip = netaddr.IPAddress(str(v.ip))
if (v_ip.is_unicast() and not v_ip.is_private() and
@@ -183,16 +203,20 @@ def _public_query(v, value):
not v_ip.is_hostmask()):
return value
def _revdns_query(v):
v_ip = netaddr.IPAddress(str(v.ip))
return v_ip.reverse_dns
def _size_query(v):
return v.size
def _subnet_query(v):
return str(v.cidr)
def _type_query(v):
if v.size == 1:
return 'address'
@@ -202,13 +226,16 @@ def _type_query(v):
else:
return 'network'
def _unicast_query(v, value):
if v.is_unicast():
return value
def _version_query(v):
return v.version
def _wrap_query(v, vtype, value):
if v.version == 6:
if vtype == 'address':
@@ -224,41 +251,48 @@ def _bare_query(v):
v.dialect = netaddr.mac_bare
return str(v)
def _bool_hwaddr_query(v):
if v:
return True
def _int_hwaddr_query(v):
return int(v)
def _cisco_query(v):
v.dialect = netaddr.mac_cisco
return str(v)
def _empty_hwaddr_query(v, value):
if v:
return value
def _linux_query(v):
v.dialect = mac_linux
return str(v)
def _postgresql_query(v):
v.dialect = netaddr.mac_pgsql
return str(v)
def _unix_query(v):
v.dialect = netaddr.mac_unix
return str(v)
def _win_query(v):
v.dialect = netaddr.mac_eui48
return str(v)
# ---- IP address and network filters ----
def ipaddr(value, query = '', version = False, alias = 'ipaddr'):
def ipaddr(value, query='', version=False, alias='ipaddr'):
''' Check if string is an IP address or network and filter it '''
query_func_extra_args = {
@@ -276,7 +310,8 @@ def ipaddr(value, query = '', version = False, alias = 'ipaddr'):
'public': ('value',),
'unicast': ('value',),
'wrap': ('vtype', 'value'),
}
}
query_func_map = {
'': _empty_ipaddr_query,
'6to4': _6to4_query,
@@ -316,7 +351,7 @@ def ipaddr(value, query = '', version = False, alias = 'ipaddr'):
'v6': _ipv6_query,
'version': _version_query,
'wrap': _wrap_query,
}
}
vtype = None
@@ -421,7 +456,7 @@ def ipaddr(value, query = '', version = False, alias = 'ipaddr'):
# that string is a valid subnet, if so, we can check later if given IP
# address/network is inside that specific subnet
try:
### ?? 6to4 and link-local were True here before. Should they still?
# ?? 6to4 and link-local were True here before. Should they still?
if query and (query not in query_func_map or query == 'cidr_lookup') and ipaddr(query, 'network'):
iplist = netaddr.IPSet([netaddr.IPNetwork(query)])
query = 'cidr_lookup'
@@ -463,19 +498,19 @@ def ipaddr(value, query = '', version = False, alias = 'ipaddr'):
return False
def ipwrap(value, query = ''):
def ipwrap(value, query=''):
try:
if isinstance(value, (list, tuple, types.GeneratorType)):
_ret = []
for element in value:
if ipaddr(element, query, version = False, alias = 'ipwrap'):
if ipaddr(element, query, version=False, alias='ipwrap'):
_ret.append(ipaddr(element, 'wrap'))
else:
_ret.append(element)
return _ret
else:
_ret = ipaddr(value, query, version = False, alias = 'ipwrap')
_ret = ipaddr(value, query, version=False, alias='ipwrap')
if _ret:
return ipaddr(_ret, 'wrap')
else:
@@ -485,12 +520,12 @@ def ipwrap(value, query = ''):
return value
def ipv4(value, query = ''):
return ipaddr(value, query, version = 4, alias = 'ipv4')
def ipv4(value, query=''):
return ipaddr(value, query, version=4, alias='ipv4')
def ipv6(value, query = ''):
return ipaddr(value, query, version = 6, alias = 'ipv6')
def ipv6(value, query=''):
return ipaddr(value, query, version=6, alias='ipv6')
# Split given subnet into smaller subnets or find out the biggest subnet of
@@ -511,7 +546,7 @@ def ipv6(value, query = ''):
#
# - address | ipsubnet(cidr, index)
# returns next indexed subnet which contains given address
def ipsubnet(value, query = '', index = 'x'):
def ipsubnet(value, query='', index='x'):
''' Manipulate IPv4/IPv6 subnets '''
try:
@@ -563,6 +598,7 @@ def ipsubnet(value, query = '', index = 'x'):
return False
# Returns the nth host within a network described by value.
# Usage:
#
@@ -594,11 +630,12 @@ def nthhost(value, query=''):
return False
# Returns the SLAAC address within a network for a given HW/MAC address.
# Usage:
#
# - prefix | slaac(mac)
def slaac(value, query = ''):
def slaac(value, query=''):
''' Get the SLAAC address within given network '''
try:
vtype = ipaddr(value, 'type')
@@ -618,7 +655,7 @@ def slaac(value, query = ''):
return False
try:
mac = hwaddr(query, alias = 'slaac')
mac = hwaddr(query, alias='slaac')
eui = netaddr.EUI(mac)
except:
@@ -628,13 +665,13 @@ def slaac(value, query = ''):
# ---- HWaddr / MAC address filters ----
def hwaddr(value, query = '', alias = 'hwaddr'):
def hwaddr(value, query='', alias='hwaddr'):
''' Check if string is a HW/MAC address and filter it '''
query_func_extra_args = {
'': ('value',),
}
}
query_func_map = {
'': _empty_hwaddr_query,
'bare': _bare_query,
@@ -648,7 +685,7 @@ def hwaddr(value, query = '', alias = 'hwaddr'):
'psql': _postgresql_query,
'unix': _unix_query,
'win': _win_query,
}
}
try:
v = netaddr.EUI(value)
@@ -666,23 +703,26 @@ def hwaddr(value, query = '', alias = 'hwaddr'):
return False
def macaddr(value, query = ''):
return hwaddr(value, query, alias = 'macaddr')
def macaddr(value, query=''):
return hwaddr(value, query, alias='macaddr')
def _need_netaddr(f_name, *args, **kwargs):
raise errors.AnsibleFilterError('The {0} filter requires python-netaddr be'
' installed on the ansible controller'.format(f_name))
raise errors.AnsibleFilterError('The %s filter requires python-netaddr be '
'installed on the ansible controller' % f_name)
def ip4_hex(arg):
''' Convert an IPv4 address to Hexadecimal notation '''
numbers = list(map(int, arg.split('.')))
return '{:02x}{:02x}{:02x}{:02x}'.format(*numbers)
# ---- Ansible filters ----
# ---- Ansible filters ----
class FilterModule(object):
''' IP address and network manipulation filters '''
filter_map = {
filter_map = {
# IP addresses and networks
'ipaddr': ipaddr,
'ipwrap': ipwrap,

View File

@@ -39,6 +39,7 @@ def json_query(data, expr):
return jmespath.search(expr, data)
class FilterModule(object):
''' Query filter '''

View File

@@ -20,16 +20,16 @@ from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import math
import collections
import itertools
import math
from ansible import errors
from ansible.module_utils import basic
def unique(a):
if isinstance(a,collections.Hashable):
if isinstance(a, collections.Hashable):
c = set(a)
else:
c = []
@@ -38,38 +38,44 @@ def unique(a):
c.append(x)
return c
def intersect(a, b):
if isinstance(a,collections.Hashable) and isinstance(b,collections.Hashable):
if isinstance(a, collections.Hashable) and isinstance(b, collections.Hashable):
c = set(a) & set(b)
else:
c = unique(filter(lambda x: x in b, a))
return c
def difference(a, b):
if isinstance(a,collections.Hashable) and isinstance(b,collections.Hashable):
if isinstance(a, collections.Hashable) and isinstance(b, collections.Hashable):
c = set(a) - set(b)
else:
c = unique(filter(lambda x: x not in b, a))
return c
def symmetric_difference(a, b):
if isinstance(a,collections.Hashable) and isinstance(b,collections.Hashable):
if isinstance(a, collections.Hashable) and isinstance(b, collections.Hashable):
c = set(a) ^ set(b)
else:
c = unique(filter(lambda x: x not in intersect(a,b), union(a,b)))
c = unique(filter(lambda x: x not in intersect(a, b), union(a, b)))
return c
def union(a, b):
if isinstance(a,collections.Hashable) and isinstance(b,collections.Hashable):
if isinstance(a, collections.Hashable) and isinstance(b, collections.Hashable):
c = set(a) | set(b)
else:
c = unique(a + b)
return c
def min(a):
_min = __builtins__.get('min')
return _min(a)
def max(a):
_max = __builtins__.get('max')
return _max(a)
@@ -97,7 +103,7 @@ def inversepower(x, base=2):
if base == 2:
return math.sqrt(x)
else:
return math.pow(x, 1.0/float(base))
return math.pow(x, 1.0 / float(base))
except TypeError as e:
raise errors.AnsibleFilterError('root() can only be used on numbers: %s' % str(e))
@@ -109,6 +115,7 @@ def human_readable(size, isbits=False, unit=None):
except:
raise errors.AnsibleFilterError("human_readable() can't interpret following string: %s" % size)
def human_to_bytes(size, default_unit=None, isbits=False):
''' Return bytes count from a human readable string '''
try:
@@ -116,14 +123,15 @@ def human_to_bytes(size, default_unit=None, isbits=False):
except:
raise errors.AnsibleFilterError("human_to_bytes() can't interpret following string: %s" % size)
class FilterModule(object):
''' Ansible math jinja2 filters '''
def filters(self):
filters = {
# general math
'min' : min,
'max' : max,
'min': min,
'max': max,
# exponents and logarithms
'log': logarithm,
@@ -131,7 +139,7 @@ class FilterModule(object):
'root': inversepower,
# set theory
'unique' : unique,
'unique': unique,
'intersect': intersect,
'difference': difference,
'symmetric_difference': symmetric_difference,
@@ -142,8 +150,8 @@ class FilterModule(object):
'combinations': itertools.combinations,
# computer theory
'human_readable' : human_readable,
'human_to_bytes' : human_to_bytes,
'human_readable': human_readable,
'human_to_bytes': human_to_bytes,
}

View File

@@ -85,8 +85,7 @@ class BaseInventoryPlugin(object):
def _compose(self, template, variables):
''' helper method for pluigns to compose variables for Ansible based on jinja2 expression and inventory vars'''
t = Templar(loader=self.loader, variables=variables)
return t.do_template('%s%s%s' % (t.environment.variable_start_string,template,t.environment.variable_end_string), disable_lookups=True)
return t.do_template('%s%s%s' % (t.environment.variable_start_string, template, t.environment.variable_end_string), disable_lookups=True)
class BaseFileInventoryPlugin(BaseInventoryPlugin):
@@ -100,8 +99,8 @@ class BaseFileInventoryPlugin(BaseInventoryPlugin):
super(BaseFileInventoryPlugin, self).__init__(cache=None)
#### Helper methods ####
def detect_range(line = None):
# Helper methods
def detect_range(line=None):
'''
A helper function that checks a given host line to see if it contains
a range pattern described in the docstring above.
@@ -110,7 +109,8 @@ def detect_range(line = None):
'''
return '[' in line
def expand_hostname_range(line = None):
def expand_hostname_range(line=None):
'''
A helper function that expands a given line that contains a pattern
specified in top docstring, and returns a list that consists of the
@@ -137,7 +137,7 @@ def expand_hostname_range(line = None):
# - also add an optional third parameter which contains the step. (Default: 1)
# so range can be [01:10:2] -> 01 03 05 07 09
(head, nrange, tail) = line.replace('[','|',1).replace(']','|',1).split('|')
(head, nrange, tail) = line.replace('[', '|', 1).replace(']', '|', 1).split('|')
bounds = nrange.split(":")
if len(bounds) != 2 and len(bounds) != 3:
raise AnsibleError("host range must be begin:end or begin:end:step")
@@ -152,10 +152,13 @@ def expand_hostname_range(line = None):
if not end:
raise AnsibleError("host range must specify end value")
if beg[0] == '0' and len(beg) > 1:
rlen = len(beg) # range length formatting hint
rlen = len(beg) # range length formatting hint
if rlen != len(end):
raise AnsibleError("host range must specify equal-length begin and end formats")
fill = lambda _: str(_).zfill(rlen) # range sequence
def fill(x):
return str(x).zfill(rlen) # range sequence
else:
fill = str
@@ -164,17 +167,16 @@ def expand_hostname_range(line = None):
i_end = string.ascii_letters.index(end)
if i_beg > i_end:
raise AnsibleError("host range must have begin <= end")
seq = list(string.ascii_letters[i_beg:i_end+1:int(step)])
seq = list(string.ascii_letters[i_beg:i_end + 1:int(step)])
except ValueError: # not an alpha range
seq = range(int(beg), int(end)+1, int(step))
seq = range(int(beg), int(end) + 1, int(step))
for rseq in seq:
hname = ''.join((head, fill(rseq), tail))
if detect_range(hname):
all_hosts.extend( expand_hostname_range( hname ) )
all_hosts.extend(expand_hostname_range(hname))
else:
all_hosts.append(hname)
return all_hosts

View File

@@ -130,7 +130,7 @@ class InventoryModule(BaseFileInventoryPlugin):
for line in b_data.splitlines():
if line and line[0] in self.b_COMMENT_MARKERS:
# Replace is okay for comment lines
#data.append(to_text(line, errors='surrogate_then_replace'))
# data.append(to_text(line, errors='surrogate_then_replace'))
# Currently we only need these lines for accurate lineno in errors
data.append(u'')
else:
@@ -141,7 +141,6 @@ class InventoryModule(BaseFileInventoryPlugin):
except Exception as e:
raise AnsibleParserError(e)
def _raise_error(self, message):
raise AnsibleError("%s:%d: " % (self._filename, self.lineno) + message)
@@ -281,7 +280,7 @@ class InventoryModule(BaseFileInventoryPlugin):
self._raise_error("Expected key=value, got: %s" % (line))
def _parse_host_definition(self, line ):
def _parse_host_definition(self, line):
'''
Takes a single line and tries to parse it as a host definition. Returns
a list of Hosts if successful, or raises an error.

View File

@@ -80,7 +80,7 @@ class InventoryModule(BaseInventoryPlugin):
# Support inventory scripts that are not prefixed with some
# path information but happen to be in the current working
# directory when '.' is not in PATH.
cmd = [ path, "--list" ]
cmd = [path, "--list"]
try:
cache_key = self.get_cache_prefix(path)
@@ -95,7 +95,7 @@ class InventoryModule(BaseInventoryPlugin):
path = to_native(path)
if stderr:
err = to_native(stderr) + "\n"
err = to_native(stderr) + "\n"
if sp.returncode != 0:
raise AnsibleError("Inventory script (%s) had an execution error: %s " % (path, err))
@@ -140,14 +140,13 @@ class InventoryModule(BaseInventoryPlugin):
try:
got = processed.get(host, {})
except AttributeError as e:
raise AnsibleError("Improperly formatted host information for %s: %s" % (host,to_native(e)))
raise AnsibleError("Improperly formatted host information for %s: %s" % (host, to_native(e)))
self.populate_host_vars(host, got, group)
except Exception as e:
raise AnsibleParserError(to_native(e))
def _parse_group(self, group, data):
self.inventory.add_group(group)
@@ -155,7 +154,7 @@ class InventoryModule(BaseInventoryPlugin):
if not isinstance(data, dict):
data = {'hosts': data}
# is not those subkeys, then simplified syntax, host with vars
elif not any(k in data for k in ('hosts','vars','children')):
elif not any(k in data for k in ('hosts', 'vars', 'children')):
data = {'hosts': [group], 'vars': data}
if 'hosts' in data:

View File

@@ -71,6 +71,7 @@ from ansible.module_utils._text import to_bytes, to_text
from ansible.parsing.utils.addresses import parse_address
from ansible.plugins.inventory import BaseFileInventoryPlugin, detect_range, expand_hostname_range
class InventoryModule(BaseFileInventoryPlugin):
NAME = 'yaml'
@@ -120,7 +121,7 @@ class InventoryModule(BaseFileInventoryPlugin):
self.inventory.add_group(group)
if isinstance(group_data, dict):
#make sure they are dicts
# make sure they are dicts
for section in ['vars', 'children', 'hosts']:
if section in group_data and isinstance(group_data[section], string_types):
group_data[section] = {group_data[section]: None}
@@ -178,4 +179,4 @@ class InventoryModule(BaseFileInventoryPlugin):
'''
Compiles the regular expressions required to parse the inventory and stores them in self.patterns.
'''
self.patterns['groupname'] = re.compile( r'''^[A-Za-z_][A-Za-z0-9_]*$''')
self.patterns['groupname'] = re.compile(r'''^[A-Za-z_][A-Za-z0-9_]*$''')

View File

@@ -60,7 +60,7 @@ class LookupBase(with_metaclass(ABCMeta, object)):
results = []
for x in a:
for y in b:
results.append(LookupBase._flatten([x,y]))
results.append(LookupBase._flatten([x, y]))
return results
@staticmethod

View File

@@ -51,6 +51,7 @@ from ansible.errors import AnsibleError
from ansible.plugins.lookup import LookupBase
from ansible.utils.listify import listify_lookup_plugin_terms
class LookupModule(LookupBase):
"""
Create the cartesian product of lists
@@ -79,4 +80,3 @@ class LookupModule(LookupBase):
raise AnsibleError("with_cartesian requires at least one element in each list")
return [self._flatten(x) for x in product(*my_list)]

View File

@@ -39,6 +39,7 @@ class CSVRecoder:
def next(self):
return self.reader.next().encode("utf-8")
class CSVReader:
"""
A CSV reader which will iterate over lines in the CSV file "f",
@@ -56,6 +57,7 @@ class CSVReader:
def __iter__(self):
return self
class LookupModule(LookupBase):
def read_csv(self, filename, key, delimiter, encoding='utf-8', dflt=None, col=1):
@@ -81,11 +83,11 @@ class LookupModule(LookupBase):
key = params[0]
paramvals = {
'col' : "1", # column to return
'default' : None,
'delimiter' : "TAB",
'file' : 'ansible.csv',
'encoding' : 'utf-8',
'col': "1", # column to return
'default': None,
'delimiter': "TAB",
'file': 'ansible.csv',
'encoding': 'utf-8',
}
# parameters specified?

View File

@@ -22,6 +22,7 @@ import collections
from ansible.errors import AnsibleError
from ansible.plugins.lookup import LookupBase
class LookupModule(LookupBase):
def run(self, terms, variables=None, **kwargs):

View File

@@ -29,11 +29,12 @@ try:
import dns.reversename
import dns.rdataclass
from dns.rdatatype import (A, AAAA, CNAME, DLV, DNAME, DNSKEY, DS, HINFO, LOC,
MX, NAPTR, NS, NSEC3PARAM, PTR, RP, SOA, SPF, SRV, SSHFP, TLSA, TXT)
MX, NAPTR, NS, NSEC3PARAM, PTR, RP, SOA, SPF, SRV, SSHFP, TLSA, TXT)
HAVE_DNS = True
except ImportError:
HAVE_DNS = False
def make_rdata_dict(rdata):
''' While the 'dig' lookup plugin supports anything which dnspython supports
out of the box, the following supported_types list describes which
@@ -42,28 +43,28 @@ def make_rdata_dict(rdata):
Note: adding support for RRSIG is hard work. :)
'''
supported_types = {
A : ['address'],
AAAA : ['address'],
CNAME : ['target'],
DNAME : ['target'],
DLV : ['algorithm', 'digest_type', 'key_tag', 'digest'],
DNSKEY : ['flags', 'algorithm', 'protocol', 'key'],
DS : ['algorithm', 'digest_type', 'key_tag', 'digest'],
HINFO : ['cpu', 'os'],
LOC : ['latitude', 'longitude', 'altitude', 'size', 'horizontal_precision', 'vertical_precision'],
MX : ['preference', 'exchange'],
NAPTR : ['order', 'preference', 'flags', 'service', 'regexp', 'replacement'],
NS : ['target'],
NSEC3PARAM : ['algorithm', 'flags', 'iterations', 'salt'],
PTR : ['target'],
RP : ['mbox', 'txt'],
# RRSIG : ['algorithm', 'labels', 'original_ttl', 'expiration', 'inception', 'signature'],
SOA : ['mname', 'rname', 'serial', 'refresh', 'retry', 'expire', 'minimum'],
SPF : ['strings'],
SRV : ['priority', 'weight', 'port', 'target'],
SSHFP : ['algorithm', 'fp_type', 'fingerprint'],
TLSA : ['usage', 'selector', 'mtype', 'cert'],
TXT : ['strings'],
A: ['address'],
AAAA: ['address'],
CNAME: ['target'],
DNAME: ['target'],
DLV: ['algorithm', 'digest_type', 'key_tag', 'digest'],
DNSKEY: ['flags', 'algorithm', 'protocol', 'key'],
DS: ['algorithm', 'digest_type', 'key_tag', 'digest'],
HINFO: ['cpu', 'os'],
LOC: ['latitude', 'longitude', 'altitude', 'size', 'horizontal_precision', 'vertical_precision'],
MX: ['preference', 'exchange'],
NAPTR: ['order', 'preference', 'flags', 'service', 'regexp', 'replacement'],
NS: ['target'],
NSEC3PARAM: ['algorithm', 'flags', 'iterations', 'salt'],
PTR: ['target'],
RP: ['mbox', 'txt'],
# RRSIG: ['algorithm', 'labels', 'original_ttl', 'expiration', 'inception', 'signature'],
SOA: ['mname', 'rname', 'serial', 'refresh', 'retry', 'expire', 'minimum'],
SPF: ['strings'],
SRV: ['priority', 'weight', 'port', 'target'],
SSHFP: ['algorithm', 'fp_type', 'fingerprint'],
TLSA: ['usage', 'selector', 'mtype', 'cert'],
TXT: ['strings'],
}
rd = {}
@@ -71,7 +72,7 @@ def make_rdata_dict(rdata):
if rdata.rdtype in supported_types:
fields = supported_types[rdata.rdtype]
for f in fields:
val = rdata.__getattribute__(f)
val = rdata.__getattribute__(f)
if isinstance(val, dns.name.Name):
val = dns.name.Name.to_text(val)
@@ -89,11 +90,11 @@ def make_rdata_dict(rdata):
if rdata.rdtype == TLSA and f == 'cert':
val = dns.rdata._hexify(rdata.cert).replace(' ', '')
rd[f] = val
rd[f] = val
return rd
# ==============================================================
# dig: Lookup DNS records
#
@@ -127,8 +128,8 @@ class LookupModule(LookupBase):
myres.use_edns(0, ednsflags=dns.flags.DO, payload=edns_size)
domain = None
qtype = 'A'
flat = True
qtype = 'A'
flat = True
rdclass = dns.rdataclass.from_text('IN')
for t in terms:
@@ -201,10 +202,10 @@ class LookupModule(LookupBase):
else:
try:
rd = make_rdata_dict(rdata)
rd['owner'] = answers.canonical_name.to_text()
rd['type'] = dns.rdatatype.to_text(rdata.rdtype)
rd['ttl'] = answers.rrset.ttl
rd['class'] = dns.rdataclass.to_text(rdata.rdclass)
rd['owner'] = answers.canonical_name.to_text()
rd['type'] = dns.rdatatype.to_text(rdata.rdtype)
rd['ttl'] = answers.rrset.ttl
rd['class'] = dns.rdataclass.to_text(rdata.rdclass)
ret.append(rd)
except Exception as e:

View File

@@ -17,17 +17,18 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
HAVE_DNS=False
HAVE_DNS = False
try:
import dns.resolver
from dns.exception import DNSException
HAVE_DNS=True
HAVE_DNS = True
except ImportError:
pass
from ansible.errors import AnsibleError
from ansible.plugins.lookup import LookupBase
from ansible.module_utils._text import to_native
from ansible.plugins.lookup import LookupBase
# ==============================================================
# DNSTXT: DNS TXT records
@@ -63,4 +64,3 @@ class LookupModule(LookupBase):
ret.append(''.join(string))
return ret

View File

@@ -21,6 +21,7 @@ import os
from ansible.plugins.lookup import LookupBase
class LookupModule(LookupBase):
def run(self, terms, variables, **kwargs):

View File

@@ -74,12 +74,13 @@ ANSIBLE_ETCD_VERSION = 'v1'
if os.getenv('ANSIBLE_ETCD_VERSION') is not None:
ANSIBLE_ETCD_VERSION = os.environ['ANSIBLE_ETCD_VERSION']
class Etcd:
def __init__(self, url=ANSIBLE_ETCD_URL, version=ANSIBLE_ETCD_VERSION,
validate_certs=True):
self.url = url
self.version = version
self.baseurl = '%s/%s/keys' % (self.url,self.version)
self.baseurl = '%s/%s/keys' % (self.url, self.version)
self.validate_certs = validate_certs
def get(self, key):
@@ -111,6 +112,7 @@ class Etcd:
return value
class LookupModule(LookupBase):
def run(self, terms, variables, **kwargs):

View File

@@ -22,10 +22,10 @@ import pwd
import grp
import stat
HAVE_SELINUX=False
HAVE_SELINUX = False
try:
import selinux
HAVE_SELINUX=True
HAVE_SELINUX = True
except ImportError:
pass
@@ -38,6 +38,7 @@ except ImportError:
from ansible.utils.display import Display
display = Display()
# If selinux fails to find a default, return an array of None
def selinux_context(path):
context = [None, None, None, None]
@@ -119,7 +120,7 @@ class LookupModule(LookupBase):
relpath = os.path.relpath(os.path.join(root, entry), path)
# Skip if relpath was already processed (from another root)
if relpath not in [ entry['path'] for entry in ret ]:
if relpath not in [entry['path'] for entry in ret]:
props = file_props(path, relpath)
if props is not None:
ret.append(props)

View File

@@ -34,11 +34,11 @@ __metaclass__ = type
# first file found with os.path.exists() is returned
# no file matches raises ansibleerror
# EXAMPLES
# - name: copy first existing file found to /some/file
# action: copy src=$item dest=/some/file
# with_first_found:
# - files: foo ${inventory_hostname} bar
# paths: /tmp/production /tmp/staging
# - name: copy first existing file found to /some/file
# action: copy src=$item dest=/some/file
# with_first_found:
# - files: foo ${inventory_hostname} bar
# paths: /tmp/production /tmp/staging
# that will look for files in this order:
# /tmp/production/foo
@@ -48,10 +48,10 @@ __metaclass__ = type
# ${inventory_hostname}
# bar
# - name: copy first existing file found to /some/file
# action: copy src=$item dest=/some/file
# with_first_found:
# - files: /some/place/foo ${inventory_hostname} /some/place/else
# - name: copy first existing file found to /some/file
# action: copy src=$item dest=/some/file
# with_first_found:
# - files: /some/place/foo ${inventory_hostname} /some/place/else
# that will look for files in this order:
# /some/place/foo
@@ -59,47 +59,47 @@ __metaclass__ = type
# /some/place/else
# example - including tasks:
# tasks:
# - include: $item
# with_first_found:
# - files: generic
# paths: tasks/staging tasks/production
# tasks:
# - include: $item
# with_first_found:
# - files: generic
# paths: tasks/staging tasks/production
# this will include the tasks in the file generic where it is found first (staging or production)
# example simple file lists
#tasks:
#- name: first found file
# action: copy src=$item dest=/etc/file.cfg
# with_first_found:
# - files: foo.${inventory_hostname} foo
# tasks:
# - name: first found file
# action: copy src=$item dest=/etc/file.cfg
# with_first_found:
# - files: foo.${inventory_hostname} foo
# example skipping if no matched files
# First_found also offers the ability to control whether or not failing
# to find a file returns an error or not
#
#- name: first found file - or skip
# action: copy src=$item dest=/etc/file.cfg
# with_first_found:
# - files: foo.${inventory_hostname}
# skip: true
# - name: first found file - or skip
# action: copy src=$item dest=/etc/file.cfg
# with_first_found:
# - files: foo.${inventory_hostname}
# skip: true
# example a role with default configuration and configuration per host
# you can set multiple terms with their own files and paths to look through.
# consider a role that sets some configuration per host falling back on a default config.
#
#- name: some configuration template
# template: src={{ item }} dest=/etc/file.cfg mode=0444 owner=root group=root
# with_first_found:
# - files:
# - ${inventory_hostname}/etc/file.cfg
# paths:
# - ../../../templates.overwrites
# - ../../../templates
# - files:
# - etc/file.cfg
# paths:
# - templates
# - name: some configuration template
# template: src={{ item }} dest=/etc/file.cfg mode=0444 owner=root group=root
# with_first_found:
# - files:
# - ${inventory_hostname}/etc/file.cfg
# paths:
# - ../../../templates.overwrites
# - ../../../templates
# - files:
# - etc/file.cfg
# paths:
# - templates
# the above will return an empty list if the files cannot be found at all
# if skip is unspecificed or if it is set to false then it will return a list
@@ -110,13 +110,13 @@ __metaclass__ = type
# first_available_file with with_first_found and leave the file listing in place
#
#
# - name: with_first_found like first_available_file
# action: copy src=$item dest=/tmp/faftest
# with_first_found:
# - ../files/foo
# - ../files/bar
# - ../files/baz
# ignore_errors: true
# - name: with_first_found like first_available_file
# action: copy src=$item dest=/tmp/faftest
# with_first_found:
# - ../files/foo
# - ../files/bar
# - ../files/baz
# ignore_errors: true
import os
@@ -145,7 +145,7 @@ class LookupModule(LookupBase):
if isinstance(term, dict):
files = term.get('files', [])
paths = term.get('paths', [])
skip = boolean(term.get('skip', False))
skip = boolean(term.get('skip', False))
filelist = files
if isinstance(files, string_types):
@@ -191,4 +191,3 @@ class LookupModule(LookupBase):
else:
raise AnsibleLookupError("No file was found when using with_first_found. Use the 'skip: true' option to allow this task to be skipped if no "
"files are found")

View File

@@ -29,9 +29,9 @@ class LookupModule(LookupBase):
# make sure term is not a list of one (list of one..) item
# return the final non list item if so
if isinstance(term,list) and len(term) == 1:
if isinstance(term, list) and len(term) == 1:
term = term[0]
if isinstance(term,list):
if isinstance(term, list):
term = self._check_list_of_one_list(term)
return term
@@ -50,7 +50,7 @@ class LookupModule(LookupBase):
# convert a variable to a list
term2 = listify_lookup_plugin_terms(term, templar=self._templar, loader=self._loader)
# but avoid converting a plain string to a list of one string
if term2 != [ term ]:
if term2 != [term]:
term = term2
if isinstance(term, list):
@@ -62,11 +62,9 @@ class LookupModule(LookupBase):
return ret
def run(self, terms, variables, **kwargs):
if not isinstance(terms, list):
raise AnsibleError("with_flattened expects a list")
return self._do_flatten(terms, variables)

View File

@@ -30,7 +30,6 @@
# necessarily be an error if a bad endpoint is specified.
#
# Requires hvac library. Install with pip.
#
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
@@ -46,6 +45,7 @@ ANSIBLE_HASHI_VAULT_ADDR = 'http://127.0.0.1:8200'
if os.getenv('VAULT_ADDR') is not None:
ANSIBLE_HASHI_VAULT_ADDR = os.environ['VAULT_ADDR']
class HashiVault:
def __init__(self, **kwargs):
try:
@@ -62,7 +62,7 @@ class HashiVault:
s_f = s.split(':')
self.secret = s_f[0]
if len(s_f)>=2:
if len(s_f) >= 2:
self.secret_field = s_f[1]
else:
self.secret_field = 'value'
@@ -108,7 +108,7 @@ class HashiVault:
if data is None:
raise AnsibleError("The secret %s doesn't seem to exist" % self.secret)
if self.secret_field=='': # secret was specified with trailing ':'
if self.secret_field == '': # secret was specified with trailing ':'
return data['data']
if self.secret_field not in data['data']:
@@ -153,4 +153,3 @@ class LookupModule(LookupBase):
ret.append(value)
return ret

View File

@@ -20,6 +20,7 @@ __metaclass__ = type
from ansible.errors import AnsibleError
from ansible.plugins.lookup import LookupBase
class LookupModule(LookupBase):
def __init__(self, basedir=None, **kwargs):
@@ -32,4 +33,3 @@ class LookupModule(LookupBase):
items = self._flatten(terms)
return list(zip(range(len(items)), items))

View File

@@ -37,7 +37,7 @@ def _parse_params(term):
params[k] = ''
thiskey = 'key'
for idp,phrase in enumerate(term.split()):
for idp, phrase in enumerate(term.split()):
for k in keys:
if ('%s=' % k) in phrase:
thiskey = k
@@ -81,7 +81,7 @@ class LookupModule(LookupBase):
basedir = self.get_basedir(variables)
self.basedir = basedir
self.cp = configparser.ConfigParser()
self.cp = configparser.ConfigParser()
ret = []
for term in terms:
@@ -89,11 +89,11 @@ class LookupModule(LookupBase):
key = params[0]
paramvals = {
'file' : 'ansible.ini',
're' : False,
'default' : None,
'section' : "global",
'type' : "ini",
'file': 'ansible.ini',
're': False,
'default': None,
'section': "global",
'type': "ini",
}
# parameters specified?

View File

@@ -19,14 +19,15 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from ansible.plugins.lookup import LookupBase
from ansible.inventory.manager import split_host_pattern, order_patterns
from ansible.plugins.lookup import LookupBase
class LookupModule(LookupBase):
def get_hosts(self, variables, pattern):
hosts = []
if pattern[0] in ('!','&'):
if pattern[0] in ('!', '&'):
obj = pattern[1:]
else:
obj = pattern
@@ -47,9 +48,9 @@ class LookupModule(LookupBase):
for p in patterns:
that = self.get_hosts(variables, p)
if p.startswith("!"):
host_list = [ h for h in host_list if h not in that]
host_list = [h for h in host_list if h not in that]
elif p.startswith("&"):
host_list = [ h for h in host_list if h in that ]
host_list = [h for h in host_list if h in that]
else:
host_list.extend(that)

View File

@@ -19,9 +19,9 @@ __metaclass__ = type
from ansible.plugins.lookup import LookupBase
class LookupModule(LookupBase):
def run(self, terms, **kwargs):
return self._flatten(terms)

View File

@@ -15,8 +15,6 @@
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
'''
@@ -56,20 +54,20 @@ except ImportError:
from ansible.plugins.lookup import LookupBase
class LookupModule(LookupBase):
def run(self, terms, **kwargs):
if not HAS_KEYRING:
raise AnsibleError(u"Can't LOOKUP(keyring): missing required python library 'keyring'")
display.vvvv(u"keyring: %s" % keyring.get_keyring() )
display.vvvv(u"keyring: %s" % keyring.get_keyring())
ret = []
for term in terms:
(servicename, username) = (term.split()[0], term.split()[1])
display.vvvv(u"username: %s, servicename: %s " %(username,servicename))
password = keyring.get_password(servicename,username)
display.vvvv(u"username: %s, servicename: %s " % (username, servicename))
password = keyring.get_password(servicename, username)
if password is None:
raise AnsibleError(u"servicename: %s for user %s not found" % (servicename, username))
ret.append(password.rstrip())
return ret

View File

@@ -23,6 +23,7 @@ from ansible.errors import AnsibleError
from ansible.plugins.lookup import LookupBase
from ansible.module_utils._text import to_text
class LookupModule(LookupBase):
def run(self, terms, variables, **kwargs):

View File

@@ -21,6 +21,7 @@ __metaclass__ = type
from ansible.plugins.lookup import LookupBase
class LookupModule(LookupBase):
def run(self, terms, **kwargs):

View File

@@ -134,7 +134,7 @@ class LookupModule(LookupBase):
item[1] = ASCENDING
elif sort_order == "DESCENDING":
item[1] = DESCENDING
#else the user knows what s/he is doing and we won't predict. PyMongo will return an error if necessary
# else the user knows what s/he is doing and we won't predict. PyMongo will return an error if necessary
def convert_mongo_result_to_valid_json(self, result):
if result is None:
@@ -151,17 +151,16 @@ class LookupModule(LookupBase):
elif isinstance(result, dict):
new_dict = {}
for key in result.keys():
value = result[key] # python2 and 3 compatible....
value = result[key] # python2 and 3 compatible....
new_dict[key] = self.convert_mongo_result_to_valid_json(value)
return new_dict
elif isinstance(result, datetime.datetime):
#epoch
return (result - datetime.datetime(1970,1,1)).total_seconds()
# epoch
return (result - datetime.datetime(1970, 1, 1)). total_seconds()
else:
#failsafe
# failsafe
return "{}".format(result)
def run(self, terms, variables, **kwargs):
ret = []
@@ -226,7 +225,7 @@ class LookupModule(LookupBase):
try:
client = MongoClient(connection_string, **extra_connection_parameters)
results = client[database][collection].find( **term )
results = client[database][collection].find(**term)
for result in results:
result = self.convert_mongo_result_to_valid_json(result)
@@ -235,6 +234,4 @@ class LookupModule(LookupBase):
except ConnectionFailure as e:
raise AnsibleError('unable to connect to database: %s' % str(e))
return ret

View File

@@ -23,6 +23,7 @@ from ansible.errors import AnsibleError, AnsibleUndefinedVariable
from ansible.plugins.lookup import LookupBase
from ansible.utils.listify import listify_lookup_plugin_terms
class LookupModule(LookupBase):
def _lookup_variables(self, terms, variables):
@@ -47,10 +48,8 @@ class LookupModule(LookupBase):
result = my_list.pop()
while len(my_list) > 0:
result2 = self._combine(result, my_list.pop())
result = result2
result = result2
new_result = []
for x in result:
new_result.append(self._flatten(x))
return new_result

View File

@@ -131,7 +131,7 @@ def _gen_candidate_chars(characters):
# getattr from string expands things like "ascii_letters" and "digits"
# into a set of characters.
chars.append(to_text(getattr(string, to_native(chars_spec), chars_spec),
errors='strict'))
errors='strict'))
chars = u''.join(chars).replace(u'"', u'').replace(u"'", u'')
return chars

View File

@@ -24,6 +24,7 @@ from distutils import util
from ansible.errors import AnsibleError
from ansible.plugins.lookup import LookupBase
# backhacked check_output with input for python 2.7
# http://stackoverflow.com/questions/10103551/passing-data-to-subprocess-check-output
def check_output2(*popenargs, **kwargs):
@@ -41,7 +42,7 @@ def check_output2(*popenargs, **kwargs):
inputdata = None
process = subprocess.Popen(*popenargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)
try:
out,err = process.communicate(inputdata)
out, err = process.communicate(inputdata)
except:
process.kill()
process.wait()
@@ -51,9 +52,10 @@ def check_output2(*popenargs, **kwargs):
cmd = kwargs.get("args")
if cmd is None:
cmd = popenargs[0]
raise subprocess.CalledProcessError(retcode, cmd, out+err)
raise subprocess.CalledProcessError(retcode, cmd, out + err)
return out
class LookupModule(LookupBase):
def parse_params(self, term):
# I went with the "traditional" param followed with space separated KV pairs.
@@ -117,7 +119,7 @@ class LookupModule(LookupBase):
newpass = self.paramvals['userpass']
else:
try:
newpass = check_output2(['pwgen','-cns',str(self.paramvals['length']), '1']).rstrip()
newpass = check_output2(['pwgen', '-cns', str(self.paramvals['length']), '1']).rstrip()
except (subprocess.CalledProcessError) as e:
raise AnsibleError(e)
return newpass
@@ -125,11 +127,11 @@ class LookupModule(LookupBase):
def update_password(self):
# generate new password, insert old lines from current result and return new password
newpass = self.get_newpass()
datetime= time.strftime("%d/%m/%Y %H:%M:%S")
msg = newpass +'\n' + '\n'.join(self.passoutput[1:])
msg+="\nlookup_pass: old password was {} (Updated on {})\n".format(self.password, datetime)
datetime = time.strftime("%d/%m/%Y %H:%M:%S")
msg = newpass + '\n' + '\n'.join(self.passoutput[1:])
msg += "\nlookup_pass: old password was {} (Updated on {})\n".format(self.password, datetime)
try:
generate = check_output2(['pass','insert','-f','-m',self.passname], input=msg)
generate = check_output2(['pass', 'insert', '-f', '-m', self.passname], input=msg)
except (subprocess.CalledProcessError) as e:
raise AnsibleError(e)
return newpass
@@ -141,7 +143,7 @@ class LookupModule(LookupBase):
datetime = time.strftime("%d/%m/%Y %H:%M:%S")
msg = newpass + '\n' + "lookup_pass: First generated by ansible on {}\n".format(datetime)
try:
generate = check_output2(['pass','insert','-f','-m',self.passname], input=msg)
generate = check_output2(['pass', 'insert', '-f', '-m', self.passname], input=msg)
except (subprocess.CalledProcessError) as e:
raise AnsibleError(e)
return newpass
@@ -160,13 +162,14 @@ class LookupModule(LookupBase):
def run(self, terms, variables, **kwargs):
result = []
self.paramvals = {
'subkey':'password',
'directory':variables.get('passwordstore'),
'create':False,
'subkey': 'password',
'directory': variables.get('passwordstore'),
'create': False,
'returnall': False,
'overwrite':False,
'userpass':'',
'length': 16}
'overwrite': False,
'userpass': '',
'length': 16,
}
for term in terms:
self.parse_params(term) # parse the input into paramvals

Some files were not shown because too many files have changed in this diff Show More