Collated PEP8 fixes (#25293)

- Make PEP8 compliant
pull/23089/merge
Dag Wieers 7 years ago committed by John R Barker
parent 2f33c1a1a1
commit 5553b20828

@ -20,25 +20,26 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import getpass
import operator
import optparse
import os
import subprocess
import re
import sys
import time
import yaml
import re
import getpass
import subprocess
from abc import ABCMeta, abstractmethod
import ansible
from ansible.release import __version__
from ansible import constants as C
from ansible.errors import AnsibleError, AnsibleOptionsError
from ansible.inventory.manager import InventoryManager
from ansible.module_utils.six import with_metaclass, string_types
from ansible.module_utils._text import to_bytes, to_text
from ansible.parsing.dataloader import DataLoader
from ansible.release import __version__
from ansible.utils.path import unfrackpath
from ansible.utils.vars import load_extra_vars, load_options_vars
from ansible.vars.manager import VariableManager
@ -79,7 +80,7 @@ class InvalidOptsParser(SortedOptParser):
add_help_option=False,
prog=parser.prog,
epilog=parser.epilog)
self.version=parser.version
self.version = parser.version
def _process_long_opt(self, rargs, values):
try:
@ -93,18 +94,19 @@ class InvalidOptsParser(SortedOptParser):
except optparse.BadOptionError:
pass
class CLI(with_metaclass(ABCMeta, object)):
''' code behind bin/ansible* programs '''
VALID_ACTIONS = []
_ITALIC = re.compile(r"I\(([^)]+)\)")
_BOLD = re.compile(r"B\(([^)]+)\)")
_BOLD = re.compile(r"B\(([^)]+)\)")
_MODULE = re.compile(r"M\(([^)]+)\)")
_URL = re.compile(r"U\(([^)]+)\)")
_CONST = re.compile(r"C\(([^)]+)\)")
_URL = re.compile(r"U\(([^)]+)\)")
_CONST = re.compile(r"C\(([^)]+)\)")
PAGER = 'less'
PAGER = 'less'
# -F (quit-if-one-screen) -R (allow raw ansi control chars)
# -S (chop long lines) -X (disable termcap init and de-init)
@ -229,7 +231,7 @@ class CLI(with_metaclass(ABCMeta, object)):
def normalize_become_options(self):
''' this keeps backwards compatibility with sudo/su self.options '''
self.options.become_ask_pass = self.options.become_ask_pass or self.options.ask_sudo_pass or self.options.ask_su_pass or C.DEFAULT_BECOME_ASK_PASS
self.options.become_user = self.options.become_user or self.options.sudo_user or self.options.su_user or C.DEFAULT_BECOME_USER
self.options.become_user = self.options.become_user or self.options.sudo_user or self.options.su_user or C.DEFAULT_BECOME_USER
if self.options.become:
pass
@ -287,78 +289,79 @@ class CLI(with_metaclass(ABCMeta, object)):
@staticmethod
def base_parser(usage="", output_opts=False, runas_opts=False, meta_opts=False, runtask_opts=False, vault_opts=False, module_opts=False,
async_opts=False, connect_opts=False, subset_opts=False, check_opts=False, inventory_opts=False, epilog=None, fork_opts=False,
runas_prompt_opts=False, desc=None):
async_opts=False, connect_opts=False, subset_opts=False, check_opts=False, inventory_opts=False, epilog=None, fork_opts=False,
runas_prompt_opts=False, desc=None):
''' create an options parser for most ansible scripts '''
# base opts
parser = SortedOptParser(usage, version=CLI.version("%prog"), description=desc, epilog=epilog)
parser.add_option('-v','--verbose', dest='verbosity', default=C.DEFAULT_VERBOSITY, action="count",
help="verbose mode (-vvv for more, -vvvv to enable connection debugging)")
parser.add_option('-v', '--verbose', dest='verbosity', default=C.DEFAULT_VERBOSITY, action="count",
help="verbose mode (-vvv for more, -vvvv to enable connection debugging)")
if inventory_opts:
parser.add_option('-i', '--inventory', '--inventory-file', dest='inventory', action="append",
help="specify inventory host path (default=[%s]) or comma separated host list. --inventory-file is deprecated" % C.DEFAULT_HOST_LIST)
help="specify inventory host path (default=[%s]) or comma separated host list. "
"--inventory-file is deprecated" % C.DEFAULT_HOST_LIST)
parser.add_option('--list-hosts', dest='listhosts', action='store_true',
help='outputs a list of matching hosts; does not execute anything else')
help='outputs a list of matching hosts; does not execute anything else')
parser.add_option('-l', '--limit', default=C.DEFAULT_SUBSET, dest='subset',
help='further limit selected hosts to an additional pattern')
help='further limit selected hosts to an additional pattern')
if module_opts:
parser.add_option('-M', '--module-path', dest='module_path', default=None,
help="prepend path(s) to module library (default=%s)" % C.DEFAULT_MODULE_PATH,
action="callback", callback=CLI.expand_tilde, type=str)
help="prepend path(s) to module library (default=%s)" % C.DEFAULT_MODULE_PATH,
action="callback", callback=CLI.expand_tilde, type=str)
if runtask_opts:
parser.add_option('-e', '--extra-vars', dest="extra_vars", action="append",
help="set additional variables as key=value or YAML/JSON", default=[])
help="set additional variables as key=value or YAML/JSON", default=[])
if fork_opts:
parser.add_option('-f','--forks', dest='forks', default=C.DEFAULT_FORKS, type='int',
help="specify number of parallel processes to use (default=%s)" % C.DEFAULT_FORKS)
parser.add_option('-f', '--forks', dest='forks', default=C.DEFAULT_FORKS, type='int',
help="specify number of parallel processes to use (default=%s)" % C.DEFAULT_FORKS)
if vault_opts:
parser.add_option('--ask-vault-pass', default=C.DEFAULT_ASK_VAULT_PASS, dest='ask_vault_pass', action='store_true',
help='ask for vault password')
help='ask for vault password')
parser.add_option('--vault-password-file', default=C.DEFAULT_VAULT_PASSWORD_FILE, dest='vault_password_file',
help="vault password file", action="callback", callback=CLI.unfrack_path, type='string')
help="vault password file", action="callback", callback=CLI.unfrack_path, type='string')
parser.add_option('--new-vault-password-file', dest='new_vault_password_file',
help="new vault password file for rekey", action="callback", callback=CLI.unfrack_path, type='string')
help="new vault password file for rekey", action="callback", callback=CLI.unfrack_path, type='string')
parser.add_option('--output', default=None, dest='output_file',
help='output file name for encrypt or decrypt; use - for stdout',
action="callback", callback=CLI.unfrack_path, type='string')
help='output file name for encrypt or decrypt; use - for stdout',
action="callback", callback=CLI.unfrack_path, type='string')
if subset_opts:
parser.add_option('-t', '--tags', dest='tags', default=[], action='append',
help="only run plays and tasks tagged with these values")
help="only run plays and tasks tagged with these values")
parser.add_option('--skip-tags', dest='skip_tags', default=[], action='append',
help="only run plays and tasks whose tags do not match these values")
help="only run plays and tasks whose tags do not match these values")
if output_opts:
parser.add_option('-o', '--one-line', dest='one_line', action='store_true',
help='condense output')
help='condense output')
parser.add_option('-t', '--tree', dest='tree', default=None,
help='log output to this directory')
help='log output to this directory')
if connect_opts:
connect_group = optparse.OptionGroup(parser, "Connection Options", "control as whom and how to connect to hosts")
connect_group.add_option('-k', '--ask-pass', default=C.DEFAULT_ASK_PASS, dest='ask_pass', action='store_true',
help='ask for connection password')
connect_group.add_option('--private-key','--key-file', default=C.DEFAULT_PRIVATE_KEY_FILE, dest='private_key_file',
help='use this file to authenticate the connection', action="callback", callback=CLI.unfrack_path, type='string')
help='ask for connection password')
connect_group.add_option('--private-key', '--key-file', default=C.DEFAULT_PRIVATE_KEY_FILE, dest='private_key_file',
help='use this file to authenticate the connection', action="callback", callback=CLI.unfrack_path, type='string')
connect_group.add_option('-u', '--user', default=C.DEFAULT_REMOTE_USER, dest='remote_user',
help='connect as this user (default=%s)' % C.DEFAULT_REMOTE_USER)
help='connect as this user (default=%s)' % C.DEFAULT_REMOTE_USER)
connect_group.add_option('-c', '--connection', dest='connection', default=C.DEFAULT_TRANSPORT,
help="connection type to use (default=%s)" % C.DEFAULT_TRANSPORT)
help="connection type to use (default=%s)" % C.DEFAULT_TRANSPORT)
connect_group.add_option('-T', '--timeout', default=C.DEFAULT_TIMEOUT, type='int', dest='timeout',
help="override the connection timeout in seconds (default=%s)" % C.DEFAULT_TIMEOUT)
help="override the connection timeout in seconds (default=%s)" % C.DEFAULT_TIMEOUT)
connect_group.add_option('--ssh-common-args', default='', dest='ssh_common_args',
help="specify common arguments to pass to sftp/scp/ssh (e.g. ProxyCommand)")
help="specify common arguments to pass to sftp/scp/ssh (e.g. ProxyCommand)")
connect_group.add_option('--sftp-extra-args', default='', dest='sftp_extra_args',
help="specify extra arguments to pass to sftp only (e.g. -f, -l)")
help="specify extra arguments to pass to sftp only (e.g. -f, -l)")
connect_group.add_option('--scp-extra-args', default='', dest='scp_extra_args',
help="specify extra arguments to pass to scp only (e.g. -l)")
help="specify extra arguments to pass to scp only (e.g. -l)")
connect_group.add_option('--ssh-extra-args', default='', dest='ssh_extra_args',
help="specify extra arguments to pass to ssh only (e.g. -R)")
help="specify extra arguments to pass to ssh only (e.g. -R)")
parser.add_option_group(connect_group)
@ -368,54 +371,55 @@ class CLI(with_metaclass(ABCMeta, object)):
runas_group = rg
# priv user defaults to root later on to enable detecting when this option was given here
runas_group.add_option("-s", "--sudo", default=C.DEFAULT_SUDO, action="store_true", dest='sudo',
help="run operations with sudo (nopasswd) (deprecated, use become)")
help="run operations with sudo (nopasswd) (deprecated, use become)")
runas_group.add_option('-U', '--sudo-user', dest='sudo_user', default=None,
help='desired sudo user (default=root) (deprecated, use become)')
help='desired sudo user (default=root) (deprecated, use become)')
runas_group.add_option('-S', '--su', default=C.DEFAULT_SU, action='store_true',
help='run operations with su (deprecated, use become)')
help='run operations with su (deprecated, use become)')
runas_group.add_option('-R', '--su-user', default=None,
help='run operations with su as this user (default=%s) (deprecated, use become)' % C.DEFAULT_SU_USER)
help='run operations with su as this user (default=%s) (deprecated, use become)' % C.DEFAULT_SU_USER)
# consolidated privilege escalation (become)
runas_group.add_option("-b", "--become", default=C.DEFAULT_BECOME, action="store_true", dest='become',
help="run operations with become (does not imply password prompting)")
help="run operations with become (does not imply password prompting)")
runas_group.add_option('--become-method', dest='become_method', default=C.DEFAULT_BECOME_METHOD, type='choice', choices=C.BECOME_METHODS,
help="privilege escalation method to use (default=%s), valid choices: [ %s ]" % (C.DEFAULT_BECOME_METHOD, ' | '.join(C.BECOME_METHODS)))
help="privilege escalation method to use (default=%s), valid choices: [ %s ]" %
(C.DEFAULT_BECOME_METHOD, ' | '.join(C.BECOME_METHODS)))
runas_group.add_option('--become-user', default=None, dest='become_user', type='string',
help='run operations as this user (default=%s)' % C.DEFAULT_BECOME_USER)
help='run operations as this user (default=%s)' % C.DEFAULT_BECOME_USER)
if runas_opts or runas_prompt_opts:
if not runas_group:
runas_group = rg
runas_group.add_option('--ask-sudo-pass', default=C.DEFAULT_ASK_SUDO_PASS, dest='ask_sudo_pass', action='store_true',
help='ask for sudo password (deprecated, use become)')
help='ask for sudo password (deprecated, use become)')
runas_group.add_option('--ask-su-pass', default=C.DEFAULT_ASK_SU_PASS, dest='ask_su_pass', action='store_true',
help='ask for su password (deprecated, use become)')
help='ask for su password (deprecated, use become)')
runas_group.add_option('-K', '--ask-become-pass', default=False, dest='become_ask_pass', action='store_true',
help='ask for privilege escalation password')
help='ask for privilege escalation password')
if runas_group:
parser.add_option_group(runas_group)
if async_opts:
parser.add_option('-P', '--poll', default=C.DEFAULT_POLL_INTERVAL, type='int', dest='poll_interval',
help="set the poll interval if using -B (default=%s)" % C.DEFAULT_POLL_INTERVAL)
help="set the poll interval if using -B (default=%s)" % C.DEFAULT_POLL_INTERVAL)
parser.add_option('-B', '--background', dest='seconds', type='int', default=0,
help='run asynchronously, failing after X seconds (default=N/A)')
help='run asynchronously, failing after X seconds (default=N/A)')
if check_opts:
parser.add_option("-C", "--check", default=False, dest='check', action='store_true',
help="don't make any changes; instead, try to predict some of the changes that may occur")
help="don't make any changes; instead, try to predict some of the changes that may occur")
parser.add_option('--syntax-check', dest='syntax', action='store_true',
help="perform a syntax check on the playbook, but do not execute it")
help="perform a syntax check on the playbook, but do not execute it")
parser.add_option("-D", "--diff", default=False, dest='diff', action='store_true',
help="when changing (small) files and templates, show the differences in those files; works great with --check")
help="when changing (small) files and templates, show the differences in those files; works great with --check")
if meta_opts:
parser.add_option('--force-handlers', default=C.DEFAULT_FORCE_HANDLERS, dest='force_handlers', action='store_true',
help="run handlers even if a task fails")
help="run handlers even if a task fails")
parser.add_option('--flush-cache', dest='flush_cache', action='store_true',
help="clear the fact cache")
help="clear the fact cache")
return parser
@ -491,7 +495,7 @@ class CLI(with_metaclass(ABCMeta, object)):
else:
# set default if it exists
if os.path.exists(C.DEFAULT_HOST_LIST):
self.options.inventory = [ C.DEFAULT_HOST_LIST ]
self.options.inventory = [C.DEFAULT_HOST_LIST]
@staticmethod
def version(prog):
@ -531,11 +535,11 @@ class CLI(with_metaclass(ABCMeta, object)):
if len(ansible_versions) < 3:
for counter in range(len(ansible_versions), 3):
ansible_versions.append(0)
return {'string': ansible_version_string.strip(),
'full': ansible_version,
'major': ansible_versions[0],
'minor': ansible_versions[1],
'revision': ansible_versions[2]}
return {'string': ansible_version_string.strip(),
'full': ansible_version,
'major': ansible_versions[0],
'minor': ansible_versions[1],
'revision': ansible_versions[2]}
@staticmethod
def _git_repo_info(repo_path):
@ -576,8 +580,7 @@ class CLI(with_metaclass(ABCMeta, object)):
offset = time.timezone
else:
offset = time.altzone
result = "({0} {1}) last updated {2} (GMT {3:+04d})".format(branch, commit,
time.strftime("%Y/%m/%d %H:%M:%S", date), int(offset / -36))
result = "({0} {1}) last updated {2} (GMT {3:+04d})".format(branch, commit, time.strftime("%Y/%m/%d %H:%M:%S", date), int(offset / -36))
else:
result = ''
return result
@ -669,7 +672,7 @@ class CLI(with_metaclass(ABCMeta, object)):
else:
try:
f = open(this_path, "rb")
vault_pass=f.read().strip()
vault_pass = f.read().strip()
f.close()
except (OSError, IOError) as e:
raise AnsibleError("Could not read vault password file %s: %s" % (this_path, e))
@ -705,4 +708,3 @@ class CLI(with_metaclass(ABCMeta, object)):
variable_manager.options_vars = load_options_vars(options, CLI.version_info(gitinfo=False))
return loader, inventory, variable_manager

@ -66,10 +66,10 @@ class AdHocCLI(CLI):
# options unique to ansible ad-hoc
self.parser.add_option('-a', '--args', dest='module_args',
help="module arguments", default=C.DEFAULT_MODULE_ARGS)
help="module arguments", default=C.DEFAULT_MODULE_ARGS)
self.parser.add_option('-m', '--module-name', dest='module_name',
help="module name to execute (default=%s)" % C.DEFAULT_MODULE_NAME,
default=C.DEFAULT_MODULE_NAME)
help="module name to execute (default=%s)" % C.DEFAULT_MODULE_NAME,
default=C.DEFAULT_MODULE_NAME)
super(AdHocCLI, self).parse()
@ -84,10 +84,10 @@ class AdHocCLI(CLI):
def _play_ds(self, pattern, async, poll):
check_raw = self.options.module_name in ('command', 'win_command', 'shell', 'win_shell', 'script', 'raw')
return dict(
name = "Ansible Ad-Hoc",
hosts = pattern,
gather_facts = 'no',
tasks = [ dict(action=dict(module=self.options.module_name, args=parse_kv(self.options.module_args, check_raw=check_raw)), async=async, poll=poll) ]
name="Ansible Ad-Hoc",
hosts=pattern,
gather_facts='no',
tasks=[dict(action=dict(module=self.options.module_name, args=parse_kv(self.options.module_args, check_raw=check_raw)), async=async, poll=poll)]
)
def run(self):
@ -98,12 +98,12 @@ class AdHocCLI(CLI):
# only thing left should be host pattern
pattern = to_text(self.args[0], errors='surrogate_or_strict')
sshpass = None
sshpass = None
becomepass = None
self.normalize_become_options()
(sshpass, becomepass) = self.ask_passwords()
passwords = { 'conn_pass': sshpass, 'become_pass': becomepass }
passwords = {'conn_pass': sshpass, 'become_pass': becomepass}
loader, inventory, variable_manager = self._play_prereqs(self.options)
@ -155,11 +155,11 @@ class AdHocCLI(CLI):
else:
cb = 'minimal'
run_tree=False
run_tree = False
if self.options.tree:
C.DEFAULT_CALLBACK_WHITELIST.append('tree')
C.TREE_DIR = self.options.tree
run_tree=True
run_tree = True
# now create a task queue manager to execute the play
self._tqm = None

@ -58,8 +58,8 @@ class ConsoleCLI(CLI, cmd.Cmd):
''' a REPL that allows for running ad-hoc tasks against a chosen inventory (based on dominis' ansible-shell).'''
modules = []
ARGUMENTS = { 'host-pattern': 'A name of a group in the inventory, a shell-like glob '
'selecting hosts in inventory or any combination of the two separated by commas.', }
ARGUMENTS = {'host-pattern': 'A name of a group in the inventory, a shell-like glob '
'selecting hosts in inventory or any combination of the two separated by commas.'}
def __init__(self, args):
@ -93,7 +93,7 @@ class ConsoleCLI(CLI, cmd.Cmd):
# options unique to shell
self.parser.add_option('--step', dest='step', action='store_true',
help="one-step-at-a-time: confirm each task before running")
help="one-step-at-a-time: confirm each task before running")
self.parser.set_defaults(cwd='*')
@ -150,7 +150,7 @@ class ConsoleCLI(CLI, cmd.Cmd):
elif module in C.IGNORE_FILES:
continue
elif module.startswith('_'):
fullpath = '/'.join([path,module])
fullpath = '/'.join([path, module])
if os.path.islink(fullpath): # avoids aliases
continue
module = module.replace('_', '', 1)
@ -184,10 +184,10 @@ class ConsoleCLI(CLI, cmd.Cmd):
try:
check_raw = self.options.module_name in ('command', 'shell', 'script', 'raw')
play_ds = dict(
name = "Ansible Shell",
hosts = self.options.cwd,
gather_facts = 'no',
tasks = [ dict(action=dict(module=module, args=parse_kv(module_args, check_raw=check_raw)))]
name="Ansible Shell",
hosts=self.options.cwd,
gather_facts='no',
tasks=[dict(action=dict(module=module, args=parse_kv(module_args, check_raw=check_raw)))]
)
play = Play().load(play_ds, variable_manager=self.variable_manager, loader=self.loader)
except Exception as e:
@ -368,7 +368,7 @@ class ConsoleCLI(CLI, cmd.Cmd):
mline = line.partition(' ')[2]
offs = len(mline) - len(text)
if self.options.cwd in ('all','*','\\'):
if self.options.cwd in ('all', '*', '\\'):
completions = self.hosts + self.groups
else:
completions = [x.name for x in self.inventory.list_hosts(self.options.cwd)]
@ -392,7 +392,7 @@ class ConsoleCLI(CLI, cmd.Cmd):
super(ConsoleCLI, self).run()
sshpass = None
sshpass = None
becomepass = None
# hosts
@ -410,7 +410,7 @@ class ConsoleCLI(CLI, cmd.Cmd):
self.normalize_become_options()
(sshpass, becomepass) = self.ask_passwords()
self.passwords = { 'conn_pass': sshpass, 'become_pass': becomepass }
self.passwords = {'conn_pass': sshpass, 'become_pass': becomepass}
self.loader, self.inventory, self.variable_manager = self._play_prereqs(self.options)

@ -21,8 +21,8 @@ __metaclass__ = type
import datetime
import os
import traceback
import textwrap
import traceback
import yaml
from ansible import constants as C
@ -60,13 +60,13 @@ class DocCLI(CLI):
)
self.parser.add_option("-l", "--list", action="store_true", default=False, dest='list_dir',
help='List available plugins')
help='List available plugins')
self.parser.add_option("-s", "--snippet", action="store_true", default=False, dest='show_snippet',
help='Show playbook snippet for specified plugin(s)')
help='Show playbook snippet for specified plugin(s)')
self.parser.add_option("-a", "--all", action="store_true", default=False, dest='all_plugins',
help='Show documentation for all plugins')
help='Show documentation for all plugins')
self.parser.add_option("-t", "--type", action="store", default='module', dest='type', type='choice',
help='Choose which plugin type', choices=['module','cache', 'connection', 'callback', 'lookup', 'strategy', 'inventory'])
help='Choose which plugin type', choices=['cache', 'callback', 'connection', 'inventory', 'lookup', 'module', 'strategy'])
super(DocCLI, self).parse()
@ -90,7 +90,7 @@ class DocCLI(CLI):
elif plugin_type == 'strategy':
loader = strategy_loader
elif plugin_type == 'inventory':
loader = PluginLoader( 'InventoryModule', 'ansible.plugins.inventory', 'inventory_plugins', 'inventory_plugins')
loader = PluginLoader('InventoryModule', 'ansible.plugins.inventory', 'inventory_plugins', 'inventory_plugins')
else:
loader = module_loader
@ -141,9 +141,9 @@ class DocCLI(CLI):
if doc is not None:
# assign from other sections
doc['plainexamples'] = plainexamples
doc['returndocs'] = returndocs
doc['metadata'] = metadata
doc['plainexamples'] = plainexamples
doc['returndocs'] = returndocs
doc['metadata'] = metadata
# generate extra data
if plugin_type == 'module':
@ -152,9 +152,9 @@ class DocCLI(CLI):
doc['action'] = True
else:
doc['action'] = False
doc['filename'] = filename
doc['now_date'] = datetime.date.today().strftime('%Y-%m-%d')
doc['docuri'] = doc[plugin_type].replace('_', '-')
doc['filename'] = filename
doc['now_date'] = datetime.date.today().strftime('%Y-%m-%d')
doc['docuri'] = doc[plugin_type].replace('_', '-')
if self.options.show_snippet and plugin_type == 'module':
text += self.get_snippet_text(doc)
@ -238,7 +238,7 @@ class DocCLI(CLI):
if len(desc) > linelimit:
desc = desc[:linelimit] + '...'
if plugin.startswith('_'): # Handle deprecated
if plugin.startswith('_'): # Handle deprecated
deprecated.append("%-*s %-*.*s" % (displace, plugin[1:], linelimit, len(desc), desc))
else:
text.append("%-*s %-*.*s" % (displace, plugin, linelimit, len(desc), desc))
@ -309,7 +309,7 @@ class DocCLI(CLI):
text.append(textwrap.fill(CLI.tty_ify(opt['description']), limit, initial_indent=opt_indent, subsequent_indent=opt_indent))
del opt['description']
aliases= ''
aliases = ''
if 'aliases' in opt:
choices = "(Aliases: " + ", ".join(str(i) for i in opt['aliases']) + ")"
del opt['aliases']
@ -319,7 +319,7 @@ class DocCLI(CLI):
del opt['choices']
default = ''
if 'default' in opt or not required:
default = "[Default: " + str(opt.pop('default', '(null)')) + "]"
default = "[Default: " + str(opt.pop('default', '(null)')) + "]"
text.append(textwrap.fill(CLI.tty_ify(aliases + choices + default), limit, initial_indent=opt_indent, subsequent_indent=opt_indent))
if 'options' in opt:
@ -361,7 +361,7 @@ class DocCLI(CLI):
display.vv("Skipping %s key cuase we don't know how to handle eet" % k)
def get_man_text(self, doc):
opt_indent=" "
opt_indent = " "
text = []
text.append("> %s (%s)\n" % (doc[self.options.type].upper(), doc['filename']))
pad = display.columns * 0.20
@ -388,11 +388,11 @@ class DocCLI(CLI):
if 'notes' in doc and doc['notes'] and len(doc['notes']) > 0:
text.append("Notes:")
for note in doc['notes']:
text.append(textwrap.fill(CLI.tty_ify(note), limit-6, initial_indent=" * ", subsequent_indent=opt_indent))
text.append(textwrap.fill(CLI.tty_ify(note), limit - 6, initial_indent=" * ", subsequent_indent=opt_indent))
if 'requirements' in doc and doc['requirements'] is not None and len(doc['requirements']) > 0:
req = ", ".join(doc['requirements'])
text.append("Requirements:%s\n" % textwrap.fill(CLI.tty_ify(req), limit-16, initial_indent=" ", subsequent_indent=opt_indent))
text.append("Requirements:%s\n" % textwrap.fill(CLI.tty_ify(req), limit - 16, initial_indent=" ", subsequent_indent=opt_indent))
if 'examples' in doc and len(doc['examples']) > 0:
text.append("Example%s:\n" % ('' if len(doc['examples']) < 2 else 's'))

@ -23,11 +23,11 @@ from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os.path
import sys
import yaml
import time
import re
import shutil
import sys
import time
import yaml
from jinja2 import Environment, FileSystemLoader
@ -36,11 +36,11 @@ from ansible.cli import CLI
from ansible.errors import AnsibleError, AnsibleOptionsError
from ansible.galaxy import Galaxy
from ansible.galaxy.api import GalaxyAPI
from ansible.galaxy.role import GalaxyRole
from ansible.galaxy.login import GalaxyLogin
from ansible.galaxy.role import GalaxyRole
from ansible.galaxy.token import GalaxyToken
from ansible.playbook.role.requirement import RoleRequirement
from ansible.module_utils._text import to_text
from ansible.playbook.role.requirement import RoleRequirement
try:
from __main__ import display
@ -52,7 +52,7 @@ except ImportError:
class GalaxyCLI(CLI):
'''command to manage Ansible roles in shared repostories, the default of which is Ansible Galaxy *https://galaxy.ansible.com*.'''
SKIP_INFO_KEYS = ("name", "description", "readme_html", "related", "summary_fields", "average_aw_composite", "average_aw_score", "url" )
SKIP_INFO_KEYS = ("name", "description", "readme_html", "related", "summary_fields", "average_aw_composite", "average_aw_score", "url")
VALID_ACTIONS = ("delete", "import", "info", "init", "install", "list", "login", "remove", "search", "setup")
def __init__(self, args):
@ -64,7 +64,6 @@ class GalaxyCLI(CLI):
super(GalaxyCLI, self).set_action()
# specific to actions
if self.action == "delete":
self.parser.set_usage("usage: %prog delete [options] github_user github_repo")
@ -113,9 +112,9 @@ class GalaxyCLI(CLI):
# options that apply to more than one action
if self.action in ['init', 'info']:
self.parser.add_option( '--offline', dest='offline', default=False, action='store_true', help="Don't query the galaxy API when creating roles")
self.parser.add_option('--offline', dest='offline', default=False, action='store_true', help="Don't query the galaxy API when creating roles")
if self.action not in ("delete","import","init","login","setup"):
if self.action not in ("delete", "import", "init", "login", "setup"):
# NOTE: while the option type=str, the default is a list, and the
# callback will set the value to a list.
self.parser.add_option('-p', '--roles-path', dest='roles_path', action="callback", callback=CLI.expand_paths, type=str,
@ -123,15 +122,15 @@ class GalaxyCLI(CLI):
help='The path to the directory containing your roles. The default is the roles_path configured in your ansible.cfg '
'file (/etc/ansible/roles if not configured)')
if self.action in ("init","install"):
if self.action in ("init", "install"):
self.parser.add_option('-f', '--force', dest='force', action='store_true', default=False, help='Force overwriting an existing role')
def parse(self):
''' create an options parser for bin/ansible '''
self.parser = CLI.base_parser(
usage = "usage: %%prog [%s] [--help] [options] ..." % "|".join(self.VALID_ACTIONS),
epilog = "\nSee '%s <command> --help' for more information on a specific command.\n\n" % os.path.basename(sys.argv[0])
usage="usage: %%prog [%s] [--help] [options] ..." % "|".join(self.VALID_ACTIONS),
epilog="\nSee '%s <command> --help' for more information on a specific command.\n\n" % os.path.basename(sys.argv[0])
)
# common
@ -190,8 +189,8 @@ class GalaxyCLI(CLI):
creates the skeleton framework of a role that complies with the galaxy metadata format.
"""
init_path = self.get_opt('init_path', './')
force = self.get_opt('force', False)
init_path = self.get_opt('init_path', './')
force = self.get_opt('force', False)
role_skeleton = self.get_opt('role_skeleton', C.GALAXY_ROLE_SKELETON)
role_name = self.args.pop(0).strip() if self.args else None
@ -203,9 +202,9 @@ class GalaxyCLI(CLI):
raise AnsibleError("- the path %s already exists, but is a file - aborting" % role_path)
elif not force:
raise AnsibleError("- the directory %s already exists."
"you can use --force to re-initialize this directory,\n"
"however it will reset any main.yml files that may have\n"
"been modified there already." % role_path)
"you can use --force to re-initialize this directory,\n"
"however it will reset any main.yml files that may have\n"
"been modified there already." % role_path)
inject_data = dict(
role_name=role_name,
@ -292,12 +291,12 @@ class GalaxyCLI(CLI):
role_info.update(gr.metadata)
req = RoleRequirement()
role_spec= req.role_yaml_parse({'role': role})
role_spec = req.role_yaml_parse({'role': role})
if role_spec:
role_info.update(role_spec)
data = self._display_role_info(role_info)
### FIXME: This is broken in both 1.9 and 2.0 as
# FIXME: This is broken in both 1.9 and 2.0 as
# _display_role_info() always returns something
if not data:
data = u"\n- the role %s was not found" % role
@ -310,7 +309,7 @@ class GalaxyCLI(CLI):
can be a name (which will be downloaded via the galaxy API and github), or it can be a local .tar.gz file.
"""
role_file = self.get_opt("role_file", None)
role_file = self.get_opt("role_file", None)
if len(self.args) == 0 and role_file is None:
# the user needs to specify one of either --role-file
@ -321,8 +320,8 @@ class GalaxyCLI(CLI):
# the role name on the command line
raise AnsibleOptionsError("- please specify a user/role name, or a roles file, but not both")
no_deps = self.get_opt("no_deps", False)
force = self.get_opt('force', False)
no_deps = self.get_opt("no_deps", False)
force = self.get_opt('force', False)
roles_left = []
if role_file:
@ -511,7 +510,7 @@ class GalaxyCLI(CLI):
raise AnsibleError("Invalid query. At least one search term, platform, galaxy tag or author must be provided.")
response = self.api.search_roles(search, platforms=self.options.platforms,
tags=self.options.galaxy_tags, author=self.options.author, page_size=page_size)
tags=self.options.galaxy_tags, author=self.options.author, page_size=page_size)
if response['count'] == 0:
display.display("No roles match your search.", color=C.COLOR_ERROR)
@ -568,9 +567,9 @@ class GalaxyCLI(CLI):
""" used to import a role into Ansible Galaxy """
colors = {
'INFO': 'normal',
'INFO': 'normal',
'WARNING': C.COLOR_WARN,
'ERROR': C.COLOR_ERROR,
'ERROR': C.COLOR_ERROR,
'SUCCESS': C.COLOR_OK,
'FAILED': C.COLOR_ERROR,
}
@ -589,19 +588,19 @@ class GalaxyCLI(CLI):
if len(task) > 1:
# found multiple roles associated with github_user/github_repo
display.display("WARNING: More than one Galaxy role associated with Github repo %s/%s." % (github_user,github_repo),
color='yellow')
display.display("WARNING: More than one Galaxy role associated with Github repo %s/%s." % (github_user, github_repo),
color='yellow')
display.display("The following Galaxy roles are being updated:" + u'\n', color=C.COLOR_CHANGED)
for t in task:
display.display('%s.%s' % (t['summary_fields']['role']['namespace'],t['summary_fields']['role']['name']), color=C.COLOR_CHANGED)
display.display('%s.%s' % (t['summary_fields']['role']['namespace'], t['summary_fields']['role']['name']), color=C.COLOR_CHANGED)
display.display(u'\nTo properly namespace this role, remove each of the above and re-import %s/%s from scratch' % (github_user, github_repo),
color=C.COLOR_CHANGED)
color=C.COLOR_CHANGED)
return 0
# found a single role as expected
display.display("Successfully submitted import request %d" % task[0]['id'])
if not self.options.wait:
display.display("Role name: %s" % task[0]['summary_fields']['role']['name'])
display.display("Repo: %s/%s" % (task[0]['github_user'],task[0]['github_repo']))
display.display("Repo: %s/%s" % (task[0]['github_user'], task[0]['github_repo']))
if self.options.check_status or self.options.wait:
# Get the status of the import
@ -634,7 +633,7 @@ class GalaxyCLI(CLI):
display.display("---------- ---------- ----------", color=C.COLOR_OK)
for secret in secrets:
display.display("%-10s %-10s %s/%s" % (secret['id'], secret['source'], secret['github_user'],
secret['github_repo']),color=C.COLOR_OK)
secret['github_repo']), color=C.COLOR_OK)
return 0
if self.options.remove_id:
@ -672,7 +671,7 @@ class GalaxyCLI(CLI):
display.display("ID User Name")
display.display("------ --------------- ----------")
for role in resp['deleted_roles']:
display.display("%-8s %-15s %s" % (role.id,role.namespace,role.name))
display.display("%-8s %-15s %s" % (role.id, role.namespace, role.name))
display.display(resp['status'])
@ -692,4 +691,3 @@ class GalaxyCLI(CLI):
if os.pathsep in data:
data = data.split(os.pathsep)[0]
return data

@ -36,18 +36,15 @@ except ImportError:
display = Display()
#---------------------------------------------------------------------------------------------------
class PlaybookCLI(CLI):
''' the tool to run *Ansible playbooks*, which are a configuration and multinode deployment system.
See the project home page (https://docs.ansible.com) for more information. '''
def parse(self):
# create parser for CLI options
parser = CLI.base_parser(
usage = "%prog [options] playbook.yml [playbook2 ...]",
usage="%prog [options] playbook.yml [playbook2 ...]",
connect_opts=True,
meta_opts=True,
runas_opts=True,
@ -63,13 +60,13 @@ class PlaybookCLI(CLI):
# ansible playbook specific opts
parser.add_option('--list-tasks', dest='listtasks', action='store_true',
help="list all tasks that would be executed")
help="list all tasks that would be executed")
parser.add_option('--list-tags', dest='listtags', action='store_true',
help="list all available tags")
help="list all available tags")
parser.add_option('--step', dest='step', action='store_true',
help="one-step-at-a-time: confirm each task before running")
help="one-step-at-a-time: confirm each task before running")
parser.add_option('--start-at-task', dest='start_at_task',
help="start the playbook at the task matching this name")
help="start the playbook at the task matching this name")
self.parser = parser
super(PlaybookCLI, self).parse()
@ -86,8 +83,8 @@ class PlaybookCLI(CLI):
# Note: slightly wrong, this is written so that implicit localhost
# Manage passwords
sshpass = None
becomepass = None
sshpass = None
becomepass = None
passwords = {}
# initial error check, to make sure all specified playbooks are accessible
@ -102,7 +99,7 @@ class PlaybookCLI(CLI):
if not self.options.listhosts and not self.options.listtasks and not self.options.listtags and not self.options.syntax:
self.normalize_become_options()
(sshpass, becomepass) = self.ask_passwords()
passwords = { 'conn_pass': sshpass, 'become_pass': becomepass }
passwords = {'conn_pass': sshpass, 'become_pass': becomepass}
loader, inventory, variable_manager = self._play_prereqs(self.options)
@ -122,7 +119,6 @@ class PlaybookCLI(CLI):
# Invalid limit
raise AnsibleError("Specified --limit does not match any hosts")
# flush fact cache if requested
if self.options.flush_cache:
self._flush_cache(inventory, variable_manager)

@ -28,8 +28,8 @@ import socket
import sys
import time
from ansible.errors import AnsibleOptionsError
from ansible.cli import CLI
from ansible.errors import AnsibleOptionsError
from ansible.module_utils._text import to_native
from ansible.plugins import module_loader
from ansible.utils.cmd_functions import run_cmd
@ -59,10 +59,10 @@ class PullCLI(CLI):
DEFAULT_PLAYBOOK = 'local.yml'
PLAYBOOK_ERRORS = {
1: 'File does not exist',
2: 'File is not readable'
2: 'File is not readable',
}
SUPPORTED_REPO_MODULES = ['git']
ARGUMENTS = { 'playbook.yml': 'The name of one the YAML format files to run as an Ansible playbook.'
ARGUMENTS = {'playbook.yml': 'The name of one the YAML format files to run as an Ansible playbook.'
'This can be a relative path within the checkout. By default, Ansible will'
"look for a playbook based on the host's fully-qualified domain name,"
'on the host hostname and finally a playbook named *local.yml*.', }
@ -85,27 +85,28 @@ class PullCLI(CLI):
# options unique to pull
self.parser.add_option('--purge', default=False, action='store_true', help='purge checkout after playbook run')
self.parser.add_option('-o', '--only-if-changed', dest='ifchanged', default=False, action='store_true',
help='only run the playbook if the repository has been updated')
help='only run the playbook if the repository has been updated')
self.parser.add_option('-s', '--sleep', dest='sleep', default=None,
help='sleep for random interval (between 0 and n number of seconds) before starting. This is a useful way to disperse git requests')
help='sleep for random interval (between 0 and n number of seconds) before starting. '
'This is a useful way to disperse git requests')
self.parser.add_option('-f', '--force', dest='force', default=False, action='store_true',
help='run the playbook even if the repository could not be updated')
help='run the playbook even if the repository could not be updated')
self.parser.add_option('-d', '--directory', dest='dest', default=None, help='directory to checkout repository to')
self.parser.add_option('-U', '--url', dest='url', default=None, help='URL of the playbook repository')
self.parser.add_option('--full', dest='fullclone', action='store_true', help='Do a full clone, instead of a shallow one.')
self.parser.add_option('-C', '--checkout', dest='checkout',
help='branch/tag/commit to checkout. Defaults to behavior of repository module.')
help='branch/tag/commit to checkout. Defaults to behavior of repository module.')
self.parser.add_option('--accept-host-key', default=False, dest='accept_host_key', action='store_true',
help='adds the hostkey for the repo url if not already added')
help='adds the hostkey for the repo url if not already added')
self.parser.add_option('-m', '--module-name', dest='module_name', default=self.DEFAULT_REPO_TYPE,
help='Repository module name, which ansible will use to check out the repo. Default is %s.' % self.DEFAULT_REPO_TYPE)
help='Repository module name, which ansible will use to check out the repo. Default is %s.' % self.DEFAULT_REPO_TYPE)
self.parser.add_option('--verify-commit', dest='verify', default=False, action='store_true',
help='verify GPG signature of checked out commit, if it fails abort running the playbook.'
' This needs the corresponding VCS module to support such an operation')
help='verify GPG signature of checked out commit, if it fails abort running the playbook. '
'This needs the corresponding VCS module to support such an operation')
self.parser.add_option('--clean', dest='clean', default=False, action='store_true',
help='modified files in the working repository will be discarded')
help='modified files in the working repository will be discarded')
self.parser.add_option('--track-subs', dest='tracksubs', default=False, action='store_true',
help='submodules will track the latest changes. This is equivalent to specifying the --remote flag to git submodule update')
help='submodules will track the latest changes. This is equivalent to specifying the --remote flag to git submodule update')
# for pull we don't want a default
self.parser.set_defaults(inventory=None)
@ -120,7 +121,7 @@ class PullCLI(CLI):
if self.options.sleep:
try:
secs = random.randint(0,int(self.options.sleep))
secs = random.randint(0, int(self.options.sleep))
self.options.sleep = secs
except ValueError:
raise AnsibleOptionsError("%s is not a number." % self.options.sleep)
@ -151,7 +152,7 @@ class PullCLI(CLI):
limit_opts = 'localhost,%s,127.0.0.1' % ','.join(set([host, node, host.split('.')[0], node.split('.')[0]]))
base_opts = '-c local '
if self.options.verbosity > 0:
base_opts += ' -%s' % ''.join([ "v" for x in range(0, self.options.verbosity) ])
base_opts += ' -%s' % ''.join(["v" for x in range(0, self.options.verbosity)])
# Attempt to use the inventory passed in as an argument
# It might not yet have been downloaded so use localhost as default
@ -165,7 +166,7 @@ class PullCLI(CLI):
else:
inv_opts = "-i 'localhost,'"
#FIXME: enable more repo modules hg/svn?
# FIXME: enable more repo modules hg/svn?
if self.options.module_name == 'git':
repo_opts = "name=%s dest=%s" % (self.options.url, self.options.dest)
if self.options.checkout:

@ -22,11 +22,11 @@ __metaclass__ = type
import os
import sys
from ansible.cli import CLI
from ansible.errors import AnsibleError, AnsibleOptionsError
from ansible.module_utils._text import to_text, to_bytes
from ansible.parsing.dataloader import DataLoader
from ansible.parsing.vault import VaultEditor
from ansible.cli import CLI
from ansible.module_utils._text import to_text, to_bytes
try:
from __main__ import display
@ -95,9 +95,9 @@ class VaultCLI(CLI):
self.parser = CLI.base_parser(
vault_opts=True,
usage = "usage: %%prog [%s] [options] [vaultfile.yml]" % "|".join(self.VALID_ACTIONS),
desc = "encryption/decryption utility for Ansbile data files",
epilog = "\nSee '%s <command> --help' for more information on a specific command.\n\n" % os.path.basename(sys.argv[0])
usage="usage: %%prog [%s] [options] [vaultfile.yml]" % "|".join(self.VALID_ACTIONS),
desc="encryption/decryption utility for Ansbile data files",
epilog="\nSee '%s <command> --help' for more information on a specific command.\n\n" % os.path.basename(sys.argv[0])
)
self.set_action()

@ -30,7 +30,7 @@ from ansible.module_utils._text import to_text
from ansible.parsing.quoting import unquote
from ansible.utils.path import makedirs_safe
BOOL_TRUE = frozenset( [ "true", "t", "y", "1", "yes", "on" ] )
BOOL_TRUE = frozenset(["true", "t", "y", "1", "yes", "on"])
def mk_boolean(value):
@ -173,48 +173,48 @@ p, CONFIG_FILE = load_config_file()
# non configurable but used as defaults
BLACKLIST_EXTS = ('.pyc', '.pyo', '.swp', '.bak', '~', '.rpm', '.md', '.txt')
# the default whitelist for cow stencils
DEFAULT_COW_WHITELIST = [ 'bud-frogs', 'bunny', 'cheese', 'daemon', 'default', 'dragon', 'elephant-in-snake', 'elephant',
'eyes', 'hellokitty', 'kitty', 'luke-koala', 'meow', 'milk', 'moofasa', 'moose', 'ren', 'sheep',
'small', 'stegosaurus', 'stimpy', 'supermilker', 'three-eyes', 'turkey', 'turtle', 'tux', 'udder',
'vader-koala', 'vader', 'www', ]
DEFAULT_COW_WHITELIST = ['bud-frogs', 'bunny', 'cheese', 'daemon', 'default', 'dragon', 'elephant-in-snake', 'elephant',
'eyes', 'hellokitty', 'kitty', 'luke-koala', 'meow', 'milk', 'moofasa', 'moose', 'ren', 'sheep',
'small', 'stegosaurus', 'stimpy', 'supermilker', 'three-eyes', 'turkey', 'turtle', 'tux', 'udder',
'vader-koala', 'vader', 'www']
# sections in config file
DEFAULTS='defaults'
DEFAULTS = 'defaults'
#### DEPRECATED VARS ### # FIXME: add deprecation warning when these get set
#none left now
# DEPRECATED VARS # FIXME: add deprecation warning when these get set
# none left now
#### DEPRECATED FEATURE TOGGLES: these will eventually be removed as it becomes the standard ####
# DEPRECATED FEATURE TOGGLES: these will eventually be removed as it becomes the standard
# If --tags or --skip-tags is given multiple times on the CLI and this is True, merge the lists of tags together.
# If False, let the last argument overwrite any previous ones.
# Behaviour is overwrite through 2.2. 2.3 overwrites but prints deprecation. 2.4 the default is to merge.
MERGE_MULTIPLE_CLI_TAGS = get_config(p, DEFAULTS, 'merge_multiple_cli_tags', 'ANSIBLE_MERGE_MULTIPLE_CLI_TAGS', True, value_type='boolean')
MERGE_MULTIPLE_CLI_TAGS = get_config(p, DEFAULTS, 'merge_multiple_cli_tags', 'ANSIBLE_MERGE_MULTIPLE_CLI_TAGS', True, value_type='boolean')
# Controls which 'precedence path' to take, remove when decide on which!
SOURCE_OVER_GROUPS = get_config(p, 'vars', 'source_over_groups', 'ANSIBLE_SOURCE_OVER_GROUPS', True, value_type='boolean')
#### GENERALLY CONFIGURABLE THINGS ####
DEFAULT_DEBUG = get_config(p, DEFAULTS, 'debug', 'ANSIBLE_DEBUG', False, value_type='boolean')
DEFAULT_VERBOSITY = get_config(p, DEFAULTS, 'verbosity', 'ANSIBLE_VERBOSITY', 0, value_type='integer')
DEFAULT_ROLES_PATH = get_config(p, DEFAULTS, 'roles_path', 'ANSIBLE_ROLES_PATH',
'~/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles', value_type='pathlist', expand_relative_paths=True)
DEFAULT_REMOTE_TMP = get_config(p, DEFAULTS, 'remote_tmp', 'ANSIBLE_REMOTE_TEMP', '~/.ansible/tmp')
DEFAULT_LOCAL_TMP = get_config(p, DEFAULTS, 'local_tmp', 'ANSIBLE_LOCAL_TEMP', '~/.ansible/tmp', value_type='tmppath')
DEFAULT_MODULE_NAME = get_config(p, DEFAULTS, 'module_name', None, 'command')
DEFAULT_FACT_PATH = get_config(p, DEFAULTS, 'fact_path', 'ANSIBLE_FACT_PATH', None, value_type='path')
DEFAULT_FORKS = get_config(p, DEFAULTS, 'forks', 'ANSIBLE_FORKS', 5, value_type='integer')
DEFAULT_MODULE_ARGS = get_config(p, DEFAULTS, 'module_args', 'ANSIBLE_MODULE_ARGS', '')
DEFAULT_MODULE_LANG = get_config(p, DEFAULTS, 'module_lang', 'ANSIBLE_MODULE_LANG', os.getenv('LANG', 'en_US.UTF-8'))
DEFAULT_MODULE_SET_LOCALE = get_config(p, DEFAULTS, 'module_set_locale','ANSIBLE_MODULE_SET_LOCALE',False, value_type='boolean')
DEFAULT_MODULE_COMPRESSION= get_config(p, DEFAULTS, 'module_compression', None, 'ZIP_DEFLATED')
DEFAULT_TIMEOUT = get_config(p, DEFAULTS, 'timeout', 'ANSIBLE_TIMEOUT', 10, value_type='integer')
DEFAULT_POLL_INTERVAL = get_config(p, DEFAULTS, 'poll_interval', 'ANSIBLE_POLL_INTERVAL', 15, value_type='integer')
DEFAULT_REMOTE_USER = get_config(p, DEFAULTS, 'remote_user', 'ANSIBLE_REMOTE_USER', None)
DEFAULT_ASK_PASS = get_config(p, DEFAULTS, 'ask_pass', 'ANSIBLE_ASK_PASS', False, value_type='boolean')
DEFAULT_PRIVATE_KEY_FILE = get_config(p, DEFAULTS, 'private_key_file', 'ANSIBLE_PRIVATE_KEY_FILE', None, value_type='path')
DEFAULT_REMOTE_PORT = get_config(p, DEFAULTS, 'remote_port', 'ANSIBLE_REMOTE_PORT', None, value_type='integer')
DEFAULT_ASK_VAULT_PASS = get_config(p, DEFAULTS, 'ask_vault_pass', 'ANSIBLE_ASK_VAULT_PASS', False, value_type='boolean')
SOURCE_OVER_GROUPS = get_config(p, 'vars', 'source_over_groups', 'ANSIBLE_SOURCE_OVER_GROUPS', True, value_type='boolean')
# GENERALLY CONFIGURABLE THINGS ####
DEFAULT_DEBUG = get_config(p, DEFAULTS, 'debug', 'ANSIBLE_DEBUG', False, value_type='boolean')
DEFAULT_VERBOSITY = get_config(p, DEFAULTS, 'verbosity', 'ANSIBLE_VERBOSITY', 0, value_type='integer')
DEFAULT_ROLES_PATH = get_config(p, DEFAULTS, 'roles_path', 'ANSIBLE_ROLES_PATH',
'~/.ansible/roles:/usr/share/ansible/roles:/etc/ansible/roles', value_type='pathlist', expand_relative_paths=True)
DEFAULT_REMOTE_TMP = get_config(p, DEFAULTS, 'remote_tmp', 'ANSIBLE_REMOTE_TEMP', '~/.ansible/tmp')
DEFAULT_LOCAL_TMP = get_config(p, DEFAULTS, 'local_tmp', 'ANSIBLE_LOCAL_TEMP', '~/.ansible/tmp', value_type='tmppath')
DEFAULT_MODULE_NAME = get_config(p, DEFAULTS, 'module_name', None, 'command')
DEFAULT_FACT_PATH = get_config(p, DEFAULTS, 'fact_path', 'ANSIBLE_FACT_PATH', None, value_type='path')
DEFAULT_FORKS = get_config(p, DEFAULTS, 'forks', 'ANSIBLE_FORKS', 5, value_type='integer')
DEFAULT_MODULE_ARGS = get_config(p, DEFAULTS, 'module_args', 'ANSIBLE_MODULE_ARGS', '')
DEFAULT_MODULE_LANG = get_config(p, DEFAULTS, 'module_lang', 'ANSIBLE_MODULE_LANG', os.getenv('LANG', 'en_US.UTF-8'))
DEFAULT_MODULE_SET_LOCALE = get_config(p, DEFAULTS, 'module_set_locale', 'ANSIBLE_MODULE_SET_LOCALE', False, value_type='boolean')
DEFAULT_MODULE_COMPRESSION = get_config(p, DEFAULTS, 'module_compression', None, 'ZIP_DEFLATED')
DEFAULT_TIMEOUT = get_config(p, DEFAULTS, 'timeout', 'ANSIBLE_TIMEOUT', 10, value_type='integer')
DEFAULT_POLL_INTERVAL = get_config(p, DEFAULTS, 'poll_interval', 'ANSIBLE_POLL_INTERVAL', 15, value_type='integer')
DEFAULT_REMOTE_USER = get_config(p, DEFAULTS, 'remote_user', 'ANSIBLE_REMOTE_USER', None)
DEFAULT_ASK_PASS = get_config(p, DEFAULTS, 'ask_pass', 'ANSIBLE_ASK_PASS', False, value_type='boolean')
DEFAULT_PRIVATE_KEY_FILE = get_config(p, DEFAULTS, 'private_key_file', 'ANSIBLE_PRIVATE_KEY_FILE', None, value_type='path')
DEFAULT_REMOTE_PORT = get_config(p, DEFAULTS, 'remote_port', 'ANSIBLE_REMOTE_PORT', None, value_type='integer')
DEFAULT_ASK_VAULT_PASS = get_config(p, DEFAULTS, 'ask_vault_pass', 'ANSIBLE_ASK_VAULT_PASS', False, value_type='boolean')
DEFAULT_VAULT_PASSWORD_FILE = get_config(p, DEFAULTS, 'vault_password_file', 'ANSIBLE_VAULT_PASSWORD_FILE', None, value_type='path')
DEFAULT_TRANSPORT = get_config(p, DEFAULTS, 'transport', 'ANSIBLE_TRANSPORT', 'smart')
DEFAULT_SCP_IF_SSH = get_config(p, 'ssh_connection', 'scp_if_ssh', 'ANSIBLE_SCP_IF_SSH', 'smart')
@ -226,12 +226,12 @@ DEFAULT_KEEP_REMOTE_FILES = get_config(p, DEFAULTS, 'keep_remote_files', 'ANSIBL
DEFAULT_HASH_BEHAVIOUR = get_config(p, DEFAULTS, 'hash_behaviour', 'ANSIBLE_HASH_BEHAVIOUR', 'replace')
DEFAULT_PRIVATE_ROLE_VARS = get_config(p, DEFAULTS, 'private_role_vars', 'ANSIBLE_PRIVATE_ROLE_VARS', False, value_type='boolean')
DEFAULT_JINJA2_EXTENSIONS = get_config(p, DEFAULTS, 'jinja2_extensions', 'ANSIBLE_JINJA2_EXTENSIONS', None)
DEFAULT_EXECUTABLE = get_config(p, DEFAULTS, 'executable', 'ANSIBLE_EXECUTABLE', '/bin/sh')
DEFAULT_GATHERING = get_config(p, DEFAULTS, 'gathering', 'ANSIBLE_GATHERING', 'implicit').lower()
DEFAULT_GATHER_SUBSET = get_config(p, DEFAULTS, 'gather_subset', 'ANSIBLE_GATHER_SUBSET', 'all').lower()
DEFAULT_GATHER_TIMEOUT = get_config(p, DEFAULTS, 'gather_timeout', 'ANSIBLE_GATHER_TIMEOUT', 10, value_type='integer')
DEFAULT_LOG_PATH = get_config(p, DEFAULTS, 'log_path', 'ANSIBLE_LOG_PATH', '', value_type='path')
DEFAULT_FORCE_HANDLERS = get_config(p, DEFAULTS, 'force_handlers', 'ANSIBLE_FORCE_HANDLERS', False, value_type='boolean')
DEFAULT_EXECUTABLE = get_config(p, DEFAULTS, 'executable', 'ANSIBLE_EXECUTABLE', '/bin/sh')
DEFAULT_GATHERING = get_config(p, DEFAULTS, 'gathering', 'ANSIBLE_GATHERING', 'implicit').lower()
DEFAULT_GATHER_SUBSET = get_config(p, DEFAULTS, 'gather_subset', 'ANSIBLE_GATHER_SUBSET', 'all').lower()
DEFAULT_GATHER_TIMEOUT = get_config(p, DEFAULTS, 'gather_timeout', 'ANSIBLE_GATHER_TIMEOUT', 10, value_type='integer')
DEFAULT_LOG_PATH = get_config(p, DEFAULTS, 'log_path', 'ANSIBLE_LOG_PATH', '', value_type='path')
DEFAULT_FORCE_HANDLERS = get_config(p, DEFAULTS, 'force_handlers', 'ANSIBLE_FORCE_HANDLERS', False, value_type='boolean')
DEFAULT_VAR_COMPRESSION_LEVEL = get_config(p, DEFAULTS, 'var_compression_level', 'ANSIBLE_VAR_COMPRESSION_LEVEL', 0, value_type='integer')
DEFAULT_INTERNAL_POLL_INTERVAL = get_config(p, DEFAULTS, 'internal_poll_interval', None, 0.001, value_type='float')
DEFAULT_ALLOW_UNSAFE_LOOKUPS = get_config(p, DEFAULTS, 'allow_unsafe_lookups', None, False, value_type='boolean')
@ -240,16 +240,16 @@ SHOW_CUSTOM_STATS = get_config(p, DEFAULTS, 'show_custom_stats', 'ANSIBLE_SHOW_C
NAMESPACE_FACTS = get_config(p, DEFAULTS, 'restrict_facts_namespace', 'ANSIBLE_RESTRICT_FACTS', False, value_type='boolean')
# Inventory
DEFAULT_HOST_LIST = get_config(p, DEFAULTS,'inventory', 'ANSIBLE_INVENTORY', '/etc/ansible/hosts', value_type='path', expand_relative_paths=True)
INVENTORY_ENABLED = get_config(p, DEFAULTS,'inventory_enabled', 'ANSIBLE_INVENTORY_ENABLED',
[ 'host_list', 'script', 'ini', 'yaml' ], value_type='list')
INVENTORY_IGNORE_EXTS = get_config(p, DEFAULTS, 'inventory_ignore_extensions', 'ANSIBLE_INVENTORY_IGNORE',
BLACKLIST_EXTS + (".orig", ".ini", ".cfg", ".retry"), value_type='list')
DEFAULT_HOST_LIST = get_config(p, DEFAULTS, 'inventory', 'ANSIBLE_INVENTORY', '/etc/ansible/hosts', value_type='path', expand_relative_paths=True)
INVENTORY_ENABLED = get_config(p, DEFAULTS, 'inventory_enabled', 'ANSIBLE_INVENTORY_ENABLED',
['host_list', 'script', 'ini', 'yaml'], value_type='list')
INVENTORY_IGNORE_EXTS = get_config(p, DEFAULTS, 'inventory_ignore_extensions', 'ANSIBLE_INVENTORY_IGNORE',
BLACKLIST_EXTS + (".orig", ".ini", ".cfg", ".retry"), value_type='list')
INVENTORY_IGNORE_PATTERNS = get_config(p, DEFAULTS, 'inventory_ignore_patterns', 'ANSIBLE_INVENTORY_IGNORE_REGEX', [], value_type='list')
VARIABLE_PRECEDENCE = get_config(p, DEFAULTS, 'precedence', 'ANSIBLE_PRECEDENCE',
['all_inventory', 'groups_inventory', 'all_plugins_inventory', 'all_plugins_play',
'groups_plugins_inventory', 'groups_plugins_play'],
value_type='list')
VARIABLE_PRECEDENCE = get_config(p, DEFAULTS, 'precedence', 'ANSIBLE_PRECEDENCE',
['all_inventory', 'groups_inventory', 'all_plugins_inventory', 'all_plugins_play',
'groups_plugins_inventory', 'groups_plugins_play'],
value_type='list')
# Static includes
DEFAULT_TASK_INCLUDES_STATIC = get_config(p, DEFAULTS, 'task_includes_static', 'ANSIBLE_TASK_INCLUDES_STATIC', False, value_type='boolean')
DEFAULT_HANDLER_INCLUDES_STATIC = get_config(p, DEFAULTS, 'handler_includes_static', 'ANSIBLE_HANDLER_INCLUDES_STATIC', False, value_type='boolean')
@ -455,4 +455,4 @@ IGNORE_FILES = ["COPYING", "CONTRIBUTING", "LICENSE", "README", "VERSION", "GUID
INTERNAL_RESULT_KEYS = ['add_host', 'add_group']
RESTRICTED_RESULT_KEYS = ['ansible_rsync_path', 'ansible_playbook_python']
# check all of these extensions when looking for 'variable' files which should be YAML or JSON.
YAML_FILENAME_EXTENSIONS = [ ".yml", ".yaml", ".json" ]
YAML_FILENAME_EXTENSIONS = [".yml", ".yaml", ".json"]

@ -20,8 +20,8 @@ from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import os
import sys
import re
import sys
from ansible import constants as C
from ansible.errors import AnsibleError
@ -39,6 +39,7 @@ except ImportError:
from ansible.utils.display import Display
display = Display()
class InventoryData(object):
"""
Holds inventory data (host and group objects).
@ -92,8 +93,8 @@ class InventoryData(object):
if not py_interp:
# sys.executable is not set in some cornercases. #13585
py_interp = '/usr/bin/python'
display.warning('Unable to determine python interpreter from sys.executable. Using /usr/bin/python default.'
' You can correct this by setting ansible_python_interpreter for localhost')
display.warning('Unable to determine python interpreter from sys.executable. Using /usr/bin/python default. '
'You can correct this by setting ansible_python_interpreter for localhost')
new_host.set_variable("ansible_python_interpreter", py_interp)
if "ansible_connection" not in new_host.vars:
@ -103,7 +104,6 @@ class InventoryData(object):
return new_host
def _scan_groups_for_host(self, hostname, localhost=False):
''' in case something did not update inventory correctly, fallback to group scan '''
@ -121,7 +121,6 @@ class InventoryData(object):
return found
def reconcile_inventory(self):
''' Ensure inventory basic rules, run after updates '''
@ -190,7 +189,6 @@ class InventoryData(object):
return matching_host
def add_group(self, group):
''' adds a group to inventory if not there already '''
@ -215,7 +213,7 @@ class InventoryData(object):
if host not in self.hosts:
h = Host(host, port)
self.hosts[host] = h
if self.current_source: # set to 'first source' in which host was encountered
if self.current_source: # set to 'first source' in which host was encountered
self.set_variable(host, 'inventory_file', os.path.basename(self.current_source))
self.set_variable(host, 'inventory_dir', basedir(self.current_source))
else:
@ -236,8 +234,7 @@ class InventoryData(object):
if g and host not in g.get_hosts():
g.add_host(h)
self._groups_dict_cache = {}
display.debug("Added host %s to group %s" % (host,group))
display.debug("Added host %s to group %s" % (host, group))
def set_variable(self, entity, varname, value):
''' sets a varible for an inventory object '''
@ -252,7 +249,6 @@ class InventoryData(object):
inv_object.set_variable(varname, value)
display.debug('set %s for %s' % (varname, entity))
def add_child(self, group, child):
''' Add host or group to group '''
@ -278,4 +274,3 @@ class InventoryData(object):
self._groups_dict_cache[group_name] = [h.name for h in group.get_hosts()]
return self._groups_dict_cache

@ -20,10 +20,11 @@ __metaclass__ = type
from ansible.errors import AnsibleError
from ansible.utils.vars import combine_vars
class Group:
''' a group of ansible hosts '''
#__slots__ = [ 'name', 'hosts', 'vars', 'child_groups', 'parent_groups', 'depth', '_hosts_cache' ]
# __slots__ = [ 'name', 'hosts', 'vars', 'child_groups', 'parent_groups', 'depth', '_hosts_cache' ]
def __init__(self, name=None):
@ -87,7 +88,7 @@ class Group:
self.child_groups.append(group)
# update the depth of the child
group.depth = max([self.depth+1, group.depth])
group.depth = max([self.depth + 1, group.depth])
# update the depth of the grandchildren
group._check_children_depth()
@ -105,7 +106,7 @@ class Group:
try:
for group in self.child_groups:
group.depth = max([self.depth+1, group.depth])
group.depth = max([self.depth + 1, group.depth])
group._check_children_depth()
except RuntimeError:
raise AnsibleError("The group named '%s' has a recursive dependency loop." % self.name)
@ -180,6 +181,5 @@ class Group:
try:
self.priority = int(priority)
except TypeError:
#FIXME: warn about invalid priority
# FIXME: warn about invalid priority
pass

@ -24,10 +24,11 @@ from ansible.utils.vars import combine_vars, get_unique_id
__all__ = ['Host']
class Host:
''' a single ansible host '''
#__slots__ = [ 'name', 'vars', 'groups' ]
# __slots__ = [ 'name', 'vars', 'groups' ]
def __getstate__(self):
return self.serialize()
@ -69,11 +70,11 @@ class Host:
def deserialize(self, data):
self.__init__(gen_uuid=False)
self.name = data.get('name')
self.vars = data.get('vars', dict())
self.name = data.get('name')
self.vars = data.get('vars', dict())
self.address = data.get('address', '')
self._uuid = data.get('uuid', None)
self.implicit= data.get('implicit', False)
self._uuid = data.get('uuid', None)
self.implicit = data.get('implicit', False)
groups = data.get('groups', [])
for group_data in groups:
@ -100,7 +101,6 @@ class Host:
def get_name(self):
return self.name
def populate_ancestors(self):
# populate ancestors
for group in self.groups:
@ -131,9 +131,8 @@ class Host:
else:
self.remove_group(oldg)
def set_variable(self, key, value):
self.vars[key]=value
self.vars[key] = value
def get_groups(self):
return self.groups
@ -142,10 +141,9 @@ class Host:
results = {}
results['inventory_hostname'] = self.name
results['inventory_hostname_short'] = self.name.split('.')[0]
results['group_names'] = sorted([ g.name for g in self.get_groups() if g.name != 'all'])
results['group_names'] = sorted([g.name for g in self.get_groups() if g.name != 'all'])
return combine_vars(self.vars, results)
def get_vars(self):
return combine_vars(self.vars, self.get_magic_vars())

@ -42,11 +42,12 @@ except ImportError:
HOSTS_PATTERNS_CACHE = {}
IGNORED_ALWAYS = [b"^\.", b"^host_vars$", b"^group_vars$", b"^vars_plugins$"]
IGNORED_PATTERNS = [ to_bytes(x) for x in C.INVENTORY_IGNORE_PATTERNS ]
IGNORED_PATTERNS = [to_bytes(x) for x in C.INVENTORY_IGNORE_PATTERNS]
IGNORED_EXTS = [b'%s$' % to_bytes(re.escape(x)) for x in C.INVENTORY_IGNORE_EXTS]
IGNORED = re.compile(b'|'.join(IGNORED_ALWAYS + IGNORED_PATTERNS + IGNORED_EXTS))
def order_patterns(patterns):
''' takes a list of patterns and reorders them by modifier to apply them consistently '''
@ -114,6 +115,7 @@ def split_host_pattern(pattern):
return [p.strip() for p in patterns]
class InventoryManager(object):
''' Creates and manages inventory '''
@ -135,7 +137,7 @@ class InventoryManager(object):
if sources is None:
self._sources = []
elif isinstance(sources, string_types):
self._sources = [ sources ]
self._sources = [sources]
else:
self._sources = sources
@ -175,7 +177,7 @@ class InventoryManager(object):
def _setup_inventory_plugins(self):
''' sets up loaded inventory plugins for usage '''
inventory_loader = PluginLoader( 'InventoryModule', 'ansible.plugins.inventory', 'inventory_plugins', 'inventory_plugins')
inventory_loader = PluginLoader('InventoryModule', 'ansible.plugins.inventory', 'inventory_plugins', 'inventory_plugins')
display.vvvv('setting up inventory plugins')
for name in C.INVENTORY_ENABLED:
@ -197,7 +199,7 @@ class InventoryManager(object):
if source:
if ',' not in source:
source = unfrackpath(source, follow=False)
source = unfrackpath(source, follow=False)
parse = self.parse_source(source, cache=cache)
if parse and not parsed:
parsed = True
@ -257,7 +259,7 @@ class InventoryManager(object):
display.vvv(u'Parsed %s inventory source with %s plugin' % (to_text(source), plugin_name))
break
except AnsibleParserError as e:
failures.append(u'\n* Failed to parse %s with %s inventory plugin: %s\n' %(to_text(source), plugin_name, to_text(e)))
failures.append(u'\n* Failed to parse %s with %s inventory plugin: %s\n' % (to_text(source), plugin_name, to_text(e)))
else:
display.debug(u'%s did not meet %s requirements' % (to_text(source), plugin_name))
else:
@ -279,7 +281,7 @@ class InventoryManager(object):
global HOSTS_PATTERNS_CACHE
HOSTS_PATTERNS_CACHE = {}
self._pattern_cache = {}
#FIXME: flush inventory cache
# FIXME: flush inventory cache
def refresh_inventory(self):
''' recalculate inventory '''
@ -340,11 +342,11 @@ class InventoryManager(object):
if not ignore_limits and self._subset:
# exclude hosts not in a subset, if defined
subset = self._evaluate_patterns(self._subset)
hosts = [ h for h in hosts if h in subset ]
hosts = [h for h in hosts if h in subset]
if not ignore_restrictions and self._restriction:
# exclude hosts mentioned in any restriction (ex: failed hosts)
hosts = [ h for h in hosts if h.name in self._restriction ]
hosts = [h for h in hosts if h.name in self._restriction]
seen = set()
HOSTS_PATTERNS_CACHE[pattern_hash] = [x for x in hosts if x not in seen and not seen.add(x)]
@ -365,7 +367,6 @@ class InventoryManager(object):
return hosts
def _evaluate_patterns(self, patterns):
"""
Takes a list of patterns and returns a list of matching host names,
@ -382,11 +383,11 @@ class InventoryManager(object):
else:
that = self._match_one_pattern(p)
if p.startswith("!"):
hosts = [ h for h in hosts if h not in that ]
hosts = [h for h in hosts if h not in that]
elif p.startswith("&"):
hosts = [ h for h in hosts if h in that ]
hosts = [h for h in hosts if h in that]
else:
to_append = [ h for h in that if h.name not in [ y.name for y in hosts ] ]
to_append = [h for h in that if h.name not in [y.name for y in hosts]]
hosts.extend(to_append)
return hosts
@ -500,10 +501,10 @@ class InventoryManager(object):
if end:
if end == -1:
end = len(hosts)-1
return hosts[start:end+1]
end = len(hosts) - 1
return hosts[start:end + 1]
else:
return [ hosts[start] ]
return [hosts[start]]
def _enumerate_matches(self, pattern):
"""
@ -539,13 +540,13 @@ class InventoryManager(object):
matched = True
if not matched:
display.warning("Could not match supplied host pattern, ignoring: %s" % pattern)
display.warning("Could not match supplied host pattern, ignoring: %s" % pattern)
return results
def list_hosts(self, pattern="all"):
""" return a list of hostnames for a pattern """
#FIXME: cache?
result = [ h for h in self.get_hosts(pattern) ]
# FIXME: cache?
result = [h for h in self.get_hosts(pattern)]
# allow implicit localhost if pattern matches and no other results
if len(result) == 0 and pattern in C.LOCALHOST:
@ -554,7 +555,7 @@ class InventoryManager(object):
return result
def list_groups(self):
#FIXME: cache?
# FIXME: cache?
return sorted(self._inventory.groups.keys(), key=lambda x: x)
def restrict_to_hosts(self, restriction):
@ -566,8 +567,8 @@ class InventoryManager(object):
if restriction is None:
return
elif not isinstance(restriction, list):
restriction = [ restriction ]
self._restriction = [ h.name for h in restriction ]
restriction = [restriction]
self._restriction = [h.name for h in restriction]
def subset(self, subset_pattern):
"""

@ -45,8 +45,8 @@ except LookupError:
_COMPOSED_ERROR_HANDLERS = frozenset((None, 'surrogate_or_escape',
'surrogate_or_strict',
'surrogate_then_replace'))
'surrogate_or_strict',
'surrogate_then_replace'))
def to_bytes(obj, encoding='utf-8', errors=None, nonstring='simplerepr'):

@ -44,6 +44,7 @@ AXAPI_VPORT_PROTOCOLS = {
'https': 12,
}
def a10_argument_spec():
return dict(
host=dict(type='str', required=True),
@ -52,11 +53,13 @@ def a10_argument_spec():
write_config=dict(type='bool', default=False)
)
def axapi_failure(result):
if 'response' in result and result['response'].get('status') == 'fail':
return True
return False
def axapi_call(module, url, post=None):
'''
Returns a datastructure based on the result of the API call
@ -81,6 +84,7 @@ def axapi_call(module, url, post=None):
rsp.close()
return data
def axapi_authenticate(module, base_url, username, password):
url = '%s&method=authenticate&username=%s&password=%s' % (base_url, username, password)
result = axapi_call(module, url)
@ -89,6 +93,7 @@ def axapi_authenticate(module, base_url, username, password):
sessid = result['session_id']
return base_url + '&session_id=' + sessid
def axapi_authenticate_v3(module, base_url, username, password):
url = base_url
auth_payload = {"credentials": {"username": username, "password": password}}
@ -98,6 +103,7 @@ def axapi_authenticate_v3(module, base_url, username, password):
signature = result['authresponse']['signature']
return signature
def axapi_call_v3(module, url, method=None, body=None, signature=None):
'''
Returns a datastructure based on the result of the API call
@ -126,6 +132,7 @@ def axapi_call_v3(module, url, method=None, body=None, signature=None):
rsp.close()
return data
def axapi_enabled_disabled(flag):
'''
The axapi uses 0/1 integer values for flags, rather than strings
@ -137,8 +144,10 @@ def axapi_enabled_disabled(flag):
else:
return 0
def axapi_get_port_protocol(protocol):
return AXAPI_PORT_PROTOCOLS.get(protocol.lower(), None)
def axapi_get_vport_protocol(protocol):
return AXAPI_VPORT_PROTOCOLS.get(protocol.lower(), None)

@ -79,9 +79,9 @@ def tower_check_mode(module):
def tower_argument_spec():
return dict(
tower_host = dict(),
tower_username = dict(),
tower_password = dict(no_log=True),
tower_verify_ssl = dict(type='bool', default=True),
tower_config_file = dict(type='path'),
tower_host=dict(),
tower_username=dict(),
tower_password=dict(no_log=True),
tower_verify_ssl=dict(type='bool', default=True),
tower_config_file=dict(type='path'),
)

@ -37,8 +37,8 @@ from ansible.module_utils.aos import *
"""
import json
from distutils.version import LooseVersion
from ansible.module_utils.pycompat24 import get_exception
from distutils.version import LooseVersion
try:
import yaml
@ -53,6 +53,7 @@ try:
except ImportError:
HAS_AOS_PYEZ = False
def check_aos_version(module, min=False):
"""
Check if the library aos-pyez is present.
@ -71,6 +72,7 @@ def check_aos_version(module, min=False):
return True
def get_aos_session(module, auth):
"""
Resume an existing session and return an AOS object.
@ -94,6 +96,7 @@ def get_aos_session(module, auth):
return aos
def find_collection_item(collection, item_name=False, item_id=False):
"""
Find collection_item based on name or id from a collection object
@ -114,6 +117,7 @@ def find_collection_item(collection, item_name=False, item_id=False):
else:
return my_dict
def content_to_dict(module, content):
"""
Convert 'content' into a Python Dict based on 'content_format'
@ -144,12 +148,12 @@ def content_to_dict(module, content):
except:
module.fail_json(msg="Unable to convert 'content' to a dict, please check if valid")
# replace the string with the dict
module.params['content'] = content_dict
return content_dict
def do_load_resource(module, collection, name):
"""
Create a new object (collection.item) by loading a datastructure directly
@ -161,10 +165,7 @@ def do_load_resource(module, collection, name):
module.fail_json(msg="An error occurred while running 'find_collection_item'")
if item.exists:
module.exit_json( changed=False,
name=item.name,
id=item.id,
value=item.value )
module.exit_json(changed=False, name=item.name, id=item.id, value=item.value)
# If not in check mode, apply the changes
if not module.check_mode:
@ -175,7 +176,4 @@ def do_load_resource(module, collection, name):
e = get_exception()
module.fail_json(msg="Unable to write item content : %r" % e)
module.exit_json( changed=True,
name=item.name,
id=item.id,
value=item.value )
module.exit_json(changed=True, name=item.name, id=item.id, value=item.value)

@ -40,6 +40,7 @@ The 'api' module provides the following common argument specs:
"""
import time
def rate_limit_argument_spec(spec=None):
"""Creates an argument spec for working with rate limiting"""
arg_spec = (dict(
@ -50,6 +51,7 @@ def rate_limit_argument_spec(spec=None):
arg_spec.update(spec)
return arg_spec
def retry_argument_spec(spec=None):
"""Creates an argument spec for working with retrying"""
arg_spec = (dict(
@ -60,41 +62,48 @@ def retry_argument_spec(spec=None):
arg_spec.update(spec)
return arg_spec
def basic_auth_argument_spec(spec=None):
arg_spec = (dict(
api_username=dict(type='str', required=False),
api_password=dict(type='str', required=False, no_log=True),
api_url=dict(type='str', required=False),
api_username=dict(type='str'),
api_password=dict(type='str', no_log=True),
api_url=dict(type='str'),
validate_certs=dict(type='bool', default=True)
))
if spec:
arg_spec.update(spec)
return arg_spec
def rate_limit(rate=None, rate_limit=None):
"""rate limiting decorator"""
minrate = None
if rate is not None and rate_limit is not None:
minrate = float(rate_limit) / float(rate)
def wrapper(f):
last = [0.0]
def ratelimited(*args,**kwargs):
def ratelimited(*args, **kwargs):
if minrate is not None:
elapsed = time.clock() - last[0]
left = minrate - elapsed
if left > 0:
time.sleep(left)
last[0] = time.clock()
ret = f(*args,**kwargs)
ret = f(*args, **kwargs)
return ret
return ratelimited
return wrapper
def retry(retries=None, retry_pause=1):
"""Retry decorator"""
def wrapper(f):
retry_count = 0
def retried(*args,**kwargs):
def retried(*args, **kwargs):
if retries is not None:
ret = None
while True:
@ -102,13 +111,13 @@ def retry(retries=None, retry_pause=1):
if retry_count >= retries:
raise Exception("Retry limit exceeded: %d" % retries)
try:
ret = f(*args,**kwargs)
ret = f(*args, **kwargs)
except:
pass
if ret:
break
time.sleep(retry_pause)
return ret
return retried
return wrapper

@ -25,7 +25,6 @@
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# This module initially matched the namespace of network module avi. However,
# that causes namespace import error when other modules from avi namespaces
@ -40,8 +39,7 @@ HAS_AVI = True
try:
import avi.sdk
sdk_version = getattr(avi.sdk, '__version__', None)
if ((sdk_version is None) or (sdk_version and
(parse_version(sdk_version) < parse_version('17.1')))):
if ((sdk_version is None) or (sdk_version and (parse_version(sdk_version) < parse_version('17.1')))):
# It allows the __version__ to be '' as that value is used in development builds
raise ImportError
from avi.sdk.utils.ansible_utils import avi_ansible_api

@ -1,4 +1,3 @@
#
# Copyright (c) 2016 Matt Davis, <mdavis@ansible.com>
# Chris Houseknecht, <house@redhat.com>
#
@ -16,7 +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/>.
#
import json
import os
@ -102,6 +100,7 @@ except ImportError as exc:
HAS_AZURE_EXC = exc
HAS_AZURE = False
def azure_id_to_dict(id):
pieces = re.sub(r'^\/', '', id).split('/')
result = {}
@ -121,6 +120,7 @@ AZURE_EXPECTED_VERSIONS = dict(
AZURE_MIN_RELEASE = '2.0.0rc5'
class AzureRMModuleBase(object):
def __init__(self, derived_arg_spec, bypass_checks=False, no_log=False,
@ -202,7 +202,7 @@ class AzureRMModuleBase(object):
if Version(client_version) < Version(expected_version):
self.fail("Installed {0} client version is {1}. The supported version is {2}. Try "
"`pip install azure>={3} --upgrade`".format(client_name, client_version, expected_version,
AZURE_MIN_RELEASE))
AZURE_MIN_RELEASE))
def exec_module(self, **kwargs):
self.fail("Error: {0} failed to implement exec_module method.".format(self.__class__.__name__))
@ -220,11 +220,11 @@ class AzureRMModuleBase(object):
def log(self, msg, pretty_print=False):
pass
# Use only during module development
#if self.debug:
# log_file = open('azure_rm.log', 'a')
# if pretty_print:
# if self.debug:
# log_file = open('azure_rm.log', 'a')
# if pretty_print:
# log_file.write(json.dumps(msg, indent=4, sort_keys=True))
# else:
# else:
# log_file.write(msg + u'\n')
def validate_tags(self, tags):

@ -32,7 +32,17 @@ BOOLEANS_TRUE = ['y', 'yes', 'on', '1', 'true', 1, True]
BOOLEANS_FALSE = ['n', 'no', 'off', '0', 'false', 0, False]
BOOLEANS = BOOLEANS_TRUE + BOOLEANS_FALSE
SIZE_RANGES = { 'Y': 1<<80, 'Z': 1<<70, 'E': 1<<60, 'P': 1<<50, 'T': 1<<40, 'G': 1<<30, 'M': 1<<20, 'K': 1<<10, 'B': 1 }
SIZE_RANGES = {
'Y': 1 << 80,
'Z': 1 << 70,
'E': 1 << 60,
'P': 1 << 50,
'T': 1 << 40,
'G': 1 << 30,
'M': 1 << 20,
'K': 1 << 10,
'B': 1,
}
FILE_ATTRIBUTES = {
'A': 'noatime',
@ -83,9 +93,9 @@ from itertools import repeat, chain
try:
import syslog
HAS_SYSLOG=True
HAS_SYSLOG = True
except ImportError:
HAS_SYSLOG=False
HAS_SYSLOG = False
try:
from systemd import journal
@ -93,10 +103,10 @@ try:
except ImportError:
has_journal = False
HAVE_SELINUX=False
HAVE_SELINUX = False
try:
import selinux
HAVE_SELINUX=True
HAVE_SELINUX = True
except ImportError:
pass
@ -161,8 +171,16 @@ except ImportError:
pass
from ansible.module_utils.pycompat24 import get_exception, literal_eval
from ansible.module_utils.six import (PY2, PY3, b, binary_type, integer_types,
iteritems, text_type, string_types)
from ansible.module_utils.six import (
PY2,
PY3,
b,
binary_type,
integer_types,
iteritems,
string_types,
text_type,
)
from ansible.module_utils.six.moves import map, reduce, shlex_quote
from ansible.module_utils._text import to_native, to_bytes, to_text
@ -208,33 +226,33 @@ _literal_eval = literal_eval
# is an internal implementation detail
_ANSIBLE_ARGS = None
FILE_COMMON_ARGUMENTS=dict(
src = dict(),
mode = dict(type='raw'),
owner = dict(),
group = dict(),
seuser = dict(),
serole = dict(),
selevel = dict(),
setype = dict(),
follow = dict(type='bool', default=False),
FILE_COMMON_ARGUMENTS = dict(
src=dict(),
mode=dict(type='raw'),
owner=dict(),
group=dict(),
seuser=dict(),
serole=dict(),
selevel=dict(),
setype=dict(),
follow=dict(type='bool', default=False),
# not taken by the file module, but other modules call file so it must ignore them.
content = dict(no_log=True),
backup = dict(),
force = dict(),
remote_src = dict(), # used by assemble
regexp = dict(), # used by assemble
delimiter = dict(), # used by assemble
directory_mode = dict(), # used by copy
unsafe_writes = dict(type='bool'), # should be available to any module using atomic_move
attributes = dict(aliases=['attr']),
content=dict(no_log=True),
backup=dict(),
force=dict(),
remote_src=dict(), # used by assemble
regexp=dict(), # used by assemble
delimiter=dict(), # used by assemble
directory_mode=dict(), # used by copy
unsafe_writes=dict(type='bool'), # should be available to any module using atomic_move
attributes=dict(aliases=['attr']),
)
PASSWD_ARG_RE = re.compile(r'^[-]{0,2}pass[-]?(word|wd)?')
# Can't use 07777 on Python 3, can't use 0o7777 on Python 2.4
PERM_BITS = int('07777', 8) # file mode permission bits
EXEC_PERM_BITS = int('00111', 8) # execute permission bits
EXEC_PERM_BITS = int('00111', 8) # execute permission bits
DEFAULT_PERM = int('0666', 8) # default file permission bits
@ -242,11 +260,12 @@ def get_platform():
''' what's the platform? example: Linux is a platform. '''
return platform.system()
def get_distribution():
''' return the distribution name '''
if platform.system() == 'Linux':
try:
supported_dists = platform._supported_dists + ('arch','alpine')
supported_dists = platform._supported_dists + ('arch', 'alpine')
distribution = platform.linux_distribution(supported_dists=supported_dists)[0].capitalize()
if not distribution and os.path.isfile('/etc/system-release'):
distribution = platform.linux_distribution(supported_dists=['system'])[0].capitalize()
@ -261,6 +280,7 @@ def get_distribution():
distribution = None
return distribution
def get_distribution_version():
''' return the distribution version '''
if platform.system() == 'Linux':
@ -275,6 +295,7 @@ def get_distribution_version():
distribution_version = None
return distribution_version
def get_all_subclasses(cls):
'''
used by modules like Hardware or Network fact classes to retrieve all subclasses of a given class.
@ -338,6 +359,7 @@ def json_dict_unicode_to_bytes(d, encoding='utf-8', errors='surrogate_or_strict'
else:
return d
def json_dict_bytes_to_unicode(d, encoding='utf-8', errors='surrogate_or_strict'):
''' Recursively convert dict keys and values to byte str
@ -357,6 +379,7 @@ def json_dict_bytes_to_unicode(d, encoding='utf-8', errors='surrogate_or_strict'
else:
return d
def return_values(obj):
""" Return native stringified values from datastructures.
@ -381,6 +404,7 @@ def return_values(obj):
else:
raise TypeError('Unknown parameter type: %s, %s' % (type(obj), obj))
def remove_values(value, no_log_strings):
""" Remove strings in no_log_strings from value. If value is a container
type, then remove a lot more"""
@ -489,6 +513,7 @@ def heuristic_log_sanitize(data, no_log_values=None):
output = remove_values(output, no_log_values)
return output
def bytes_to_human(size, isbits=False, unit=None):
base = 'Bytes'
@ -505,7 +530,8 @@ def bytes_to_human(size, isbits=False, unit=None):
else:
suffix = base
return '%.2f %s' % (float(size)/ limit, suffix)
return '%.2f %s' % (float(size) / limit, suffix)
def human_to_bytes(number, default_unit=None, isbits=False):
@ -555,6 +581,7 @@ def human_to_bytes(number, default_unit=None, isbits=False):
return int(round(num * limit))
def is_executable(path):
'''is the given path executable?
@ -568,6 +595,7 @@ def is_executable(path):
# execute bits are set.
return ((stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH) & os.stat(path)[stat.ST_MODE])
def _load_params():
''' read the modules parameters and store them globally.
@ -623,6 +651,7 @@ def _load_params():
'"failed": true}')
sys.exit(1)
def env_fallback(*args, **kwargs):
''' Load value from environment '''
for arg in args:
@ -631,6 +660,7 @@ def env_fallback(*args, **kwargs):
else:
raise AnsibleFallbackNotFound
def _lenient_lowercase(lst):
"""Lowercase elements of a list.
@ -644,6 +674,7 @@ def _lenient_lowercase(lst):
lowered.append(value)
return lowered
def format_attributes(attributes):
attribute_list = []
for attr in attributes:
@ -651,13 +682,15 @@ def format_attributes(attributes):
attribute_list.append(FILE_ATTRIBUTES[attr])
return attribute_list
def get_flags_from_attributes(attributes):
flags = []
for key,attr in FILE_ATTRIBUTES.items():
for key, attr in FILE_ATTRIBUTES.items():
if attr in attributes:
flags.append(key)
return ''.join(flags)
class AnsibleFallbackNotFound(Exception):
pass
@ -674,7 +707,7 @@ class AnsibleModule(object):
see library/* for examples
'''
self._name = os.path.basename(__file__) #initialize name until we can parse from options
self._name = os.path.basename(__file__) # initialize name until we can parse from options
self.argument_spec = argument_spec
self.supports_check_mode = supports_check_mode
self.check_mode = False
@ -808,15 +841,15 @@ class AnsibleModule(object):
b_path = os.path.realpath(b_path)
path = to_native(b_path)
mode = params.get('mode', None)
owner = params.get('owner', None)
group = params.get('group', None)
mode = params.get('mode', None)
owner = params.get('owner', None)
group = params.get('group', None)
# selinux related options
seuser = params.get('seuser', None)
serole = params.get('serole', None)
setype = params.get('setype', None)
selevel = params.get('selevel', None)
seuser = params.get('seuser', None)
serole = params.get('serole', None)
setype = params.get('setype', None)
selevel = params.get('selevel', None)
secontext = [seuser, serole, setype]
if self.selinux_mls_enabled():
@ -834,7 +867,6 @@ class AnsibleModule(object):
selevel=selevel, secontext=secontext, attributes=attributes,
)
# Detect whether using selinux that is MLS-aware.
# While this means you can set the level/range with
# selinux.lsetfilecon(), it may or may not mean that you
@ -853,7 +885,7 @@ class AnsibleModule(object):
if not HAVE_SELINUX:
seenabled = self.get_bin_path('selinuxenabled')
if seenabled is not None:
(rc,out,err) = self.run_command(seenabled)
(rc, out, err) = self.run_command(seenabled)
if rc == 0:
self.fail_json(msg="Aborting, target uses selinux but python bindings (libselinux-python) aren't installed!")
return False
@ -1127,7 +1159,7 @@ class AnsibleModule(object):
e = get_exception()
if os.path.islink(b_path) and e.errno == errno.EPERM: # Can't set mode on symbolic links
pass
elif e.errno in (errno.ENOENT, errno.ELOOP): # Can't set mode on broken symbolic links
elif e.errno in (errno.ENOENT, errno.ELOOP): # Can't set mode on broken symbolic links
pass
else:
raise e
@ -1154,7 +1186,7 @@ class AnsibleModule(object):
existing = self.get_file_attributes(b_path)
if existing.get('attr_flags','') != attributes:
if existing.get('attr_flags', '') != attributes:
attrcmd = self.get_bin_path('chattr')
if attrcmd:
attrcmd = [attrcmd, '=%s' % attributes, b_path]
@ -1187,14 +1219,13 @@ class AnsibleModule(object):
rc, out, err = self.run_command(attrcmd)
if rc == 0:
res = out.split(' ')[0:2]
output['attr_flags'] = res[1].replace('-','').strip()
output['attr_flags'] = res[1].replace('-', '').strip()
output['version'] = res[0].strip()
output['attributes'] = format_attributes(output['attr_flags'])
except:
pass
return output
def _symbolic_mode_to_octal(self, path_stat, symbolic_mode):
new_mode = stat.S_IMODE(path_stat.st_mode)
@ -1217,7 +1248,7 @@ class AnsibleModule(object):
return new_mode
def _apply_operation_to_mode(self, user, operator, mode_to_apply, current_mode):
if operator == '=':
if operator == '=':
if user == 'u':
mask = stat.S_IRWXU | stat.S_ISUID
elif user == 'g':
@ -1247,13 +1278,13 @@ class AnsibleModule(object):
X_perms = {
'u': {'X': stat.S_IXUSR},
'g': {'X': stat.S_IXGRP},
'o': {'X': stat.S_IXOTH}
'o': {'X': stat.S_IXOTH},
}
else:
X_perms = {
'u': {'X': 0},
'g': {'X': 0},
'o': {'X': 0}
'o': {'X': 0},
}
user_perms_to_modes = {
@ -1265,7 +1296,8 @@ class AnsibleModule(object):
't': 0,
'u': prev_mode & stat.S_IRWXU,
'g': (prev_mode & stat.S_IRWXG) << 3,
'o': (prev_mode & stat.S_IRWXO) << 6 },
'o': (prev_mode & stat.S_IRWXO) << 6,
},
'g': {
'r': stat.S_IRGRP,
'w': stat.S_IWGRP,
@ -1274,7 +1306,8 @@ class AnsibleModule(object):
't': 0,
'u': (prev_mode & stat.S_IRWXU) >> 3,
'g': prev_mode & stat.S_IRWXG,
'o': (prev_mode & stat.S_IRWXO) << 3 },
'o': (prev_mode & stat.S_IRWXO) << 3,
},
'o': {
'r': stat.S_IROTH,
'w': stat.S_IWOTH,
@ -1283,14 +1316,17 @@ class AnsibleModule(object):
't': stat.S_ISVTX,
'u': (prev_mode & stat.S_IRWXU) >> 6,
'g': (prev_mode & stat.S_IRWXG) >> 3,
'o': prev_mode & stat.S_IRWXO }
'o': prev_mode & stat.S_IRWXO,
}
}
# Insert X_perms into user_perms_to_modes
for key, value in X_perms.items():
user_perms_to_modes[key].update(value)
or_reduce = lambda mode, perm: mode | user_perms_to_modes[user][perm]
def or_reduce(mode, perm):
return mode | user_perms_to_modes[user][perm]
return reduce(or_reduce, perms, 0)
def set_fs_attributes_if_different(self, file_args, changed, diff=None, expand=True):
@ -1383,10 +1419,10 @@ class AnsibleModule(object):
def _handle_aliases(self, spec=None):
# this uses exceptions as it happens before we can safely call fail_json
aliases_results = {} #alias:canon
aliases_results = {} # alias:canon
if spec is None:
spec = self.argument_spec
for (k,v) in spec.items():
for (k, v) in spec.items():
self._legal_inputs.append(k)
aliases = v.get('aliases', None)
default = v.get('default', None)
@ -1409,7 +1445,7 @@ class AnsibleModule(object):
def _check_arguments(self, check_invalid_arguments):
self._syslog_facility = 'LOG_USER'
unsupported_parameters = set()
for (k,v) in list(self.params.items()):
for (k, v) in list(self.params.items()):
if k == '_ansible_check_mode' and v:
self.check_mode = True
@ -1444,7 +1480,7 @@ class AnsibleModule(object):
elif check_invalid_arguments and k not in self._legal_inputs:
unsupported_parameters.add(k)
#clean up internal params:
# clean up internal params:
if k.startswith('_ansible_'):
del self.params[k]
@ -1482,20 +1518,20 @@ class AnsibleModule(object):
if spec is None:
return
for check in spec:
counts = [ self._count_terms([field]) for field in check ]
non_zero = [ c for c in counts if c > 0 ]
counts = [self._count_terms([field]) for field in check]
non_zero = [c for c in counts if c > 0]
if len(non_zero) > 0:
if 0 in counts:
self.fail_json(msg="parameters are required together: %s" % (check,))
def _check_required_arguments(self, spec=None, param=None ):
def _check_required_arguments(self, spec=None, param=None):
''' ensure all required arguments are present '''
missing = []
if spec is None:
spec = self.argument_spec
if param is None:
param = self.params
for (k,v) in spec.items():
for (k, v) in spec.items():
required = v.get('required', False)
if required and k not in param:
missing.append(k)
@ -1534,8 +1570,8 @@ class AnsibleModule(object):
spec = self.argument_spec
if param is None:
param = self.params
for (k,v) in spec.items():
choices = v.get('choices',None)
for (k, v) in spec.items():
choices = v.get('choices', None)
if choices is None:
continue
if isinstance(choices, SEQUENCETYPE) and not isinstance(choices, (binary_type, text_type)):
@ -1561,8 +1597,8 @@ class AnsibleModule(object):
(param[k],) = overlap
if param[k] not in choices:
choices_str=",".join([to_native(c) for c in choices])
msg="value of %s must be one of: %s, got: %s" % (k, choices_str, param[k])
choices_str = ",".join([to_native(c) for c in choices])
msg = "value of %s must be one of: %s, got: %s" % (k, choices_str, param[k])
self.fail_json(msg=msg)
else:
self.fail_json(msg="internal error: choices for argument %s are not iterable: %s" % (k, choices))
@ -1610,7 +1646,7 @@ class AnsibleModule(object):
if isinstance(value, string_types):
return value.split(",")
elif isinstance(value, int) or isinstance(value, float):
return [ str(value) ]
return [str(value)]
raise TypeError('%s cannot be converted to a list' % type(value))
@ -1703,14 +1739,12 @@ class AnsibleModule(object):
def _check_type_raw(self, value):
return value
def _check_type_bytes(self, value):
try:
self.human_to_bytes(value)
except ValueError:
raise TypeError('%s cannot be converted to a Byte value' % type(value))
def _check_type_bits(self, value):
try:
self.human_to_bytes(value, isbits=True)
@ -1761,7 +1795,7 @@ class AnsibleModule(object):
self._check_argument_values(spec, param[k])
def _set_defaults(self, pre=True):
for (k,v) in self.argument_spec.items():
for (k, v) in self.argument_spec.items():
default = v.get('default', None)
if pre is True:
# this prevents setting defaults on required items
@ -1773,7 +1807,7 @@ class AnsibleModule(object):
self.params[k] = default
def _set_fallbacks(self):
for k,v in self.argument_spec.items():
for (k, v) in self.argument_spec.items():
fallback = v.get('fallback', (None,))
fallback_strategy = fallback[0]
fallback_args = []
@ -1856,16 +1890,14 @@ class AnsibleModule(object):
log_args = dict()
for param in self.params:
canon = self.aliases.get(param, param)
canon = self.aliases.get(param, param)
arg_opts = self.argument_spec.get(canon, {})
no_log = arg_opts.get('no_log', False)
if self.boolean(no_log):
log_args[param] = 'NOT_LOGGING_PARAMETER'
# try to capture all passwords/passphrase named fields missed by no_log
elif PASSWORD_MATCH.search(param) and \
arg_opts.get('type', 'str') != 'bool' and \
not arg_opts.get('choices', False):
elif PASSWORD_MATCH.search(param) and arg_opts.get('type', 'str') != 'bool' and not arg_opts.get('choices', False):
# skip boolean and enums as they are about 'password' state
log_args[param] = 'NOT_LOGGING_PASSWORD'
self.warn('Module did not set no_log for %s' % param)
@ -1885,11 +1917,10 @@ class AnsibleModule(object):
self.log(msg, log_args=log_args)
def _set_cwd(self):
try:
cwd = os.getcwd()
if not os.access(cwd, os.F_OK|os.R_OK):
if not os.access(cwd, os.F_OK | os.R_OK):
raise Exception()
return cwd
except:
@ -1897,7 +1928,7 @@ class AnsibleModule(object):
# Try and move to a neutral location to prevent errors
for cwd in [os.path.expandvars('$HOME'), tempfile.gettempdir()]:
try:
if os.access(cwd, os.F_OK|os.R_OK):
if os.access(cwd, os.F_OK | os.R_OK):
os.chdir(cwd)
return cwd
except:
@ -2011,7 +2042,7 @@ class AnsibleModule(object):
def exit_json(self, **kwargs):
''' return from the module, without error '''
if not 'changed' in kwargs:
if 'changed' not in kwargs:
kwargs['changed'] = False
self.do_cleanup_files()
@ -2024,7 +2055,7 @@ class AnsibleModule(object):
assert 'msg' in kwargs, "implementation error -- msg to explain the error is required"
kwargs['failed'] = True
if not 'changed' in kwargs:
if 'changed' not in kwargs:
kwargs['changed'] = False
self.do_cleanup_files()
@ -2175,7 +2206,7 @@ class AnsibleModule(object):
native_suffix = os.path.basename(b_dest)
native_prefix = b('.ansible_tmp')
try:
tmp_dest_fd, tmp_dest_name = tempfile.mkstemp( prefix=native_prefix, dir=native_dest_dir, suffix=native_suffix)
tmp_dest_fd, tmp_dest_name = tempfile.mkstemp(prefix=native_prefix, dir=native_dest_dir, suffix=native_suffix)
except (OSError, IOError):
e = get_exception()
self.fail_json(msg='The destination directory (%s) is not writable by the current user. Error was: %s' % (os.path.dirname(dest), e))
@ -2261,7 +2292,6 @@ class AnsibleModule(object):
e = get_exception()
self.fail_json(msg='Could not write data to file (%s) from (%s): %s' % (dest, src, e), exception=traceback.format_exc())
def _read_from_pipes(self, rpipes, rfds, file_descriptor):
data = b('')
if file_descriptor in rfds:
@ -2359,7 +2389,7 @@ class AnsibleModule(object):
# expand things like $HOME and ~
if not shell:
args = [ os.path.expanduser(os.path.expandvars(x)) for x in args if x is not None ]
args = [os.path.expanduser(os.path.expandvars(x)) for x in args if x is not None]
rc = 0
msg = None
@ -2387,9 +2417,9 @@ class AnsibleModule(object):
# Clean out python paths set by ansiballz
if 'PYTHONPATH' in os.environ:
pypaths = os.environ['PYTHONPATH'].split(':')
pypaths = [x for x in pypaths \
if not x.endswith('/ansible_modlib.zip') \
and not x.endswith('/debug_dir')]
pypaths = [x for x in pypaths
if not x.endswith('/ansible_modlib.zip') and
not x.endswith('/debug_dir')]
os.environ['PYTHONPATH'] = ':'.join(pypaths)
if not os.environ['PYTHONPATH']:
del os.environ['PYTHONPATH']
@ -2510,7 +2540,7 @@ class AnsibleModule(object):
self.fail_json(rc=e.errno, msg=to_native(e), cmd=clean_args)
except Exception:
e = get_exception()
self.log("Error Executing CMD:%s Exception:%s" % (clean_args,to_native(traceback.format_exc())))
self.log("Error Executing CMD:%s Exception:%s" % (clean_args, to_native(traceback.format_exc())))
self.fail_json(rc=257, msg=to_native(e), exception=traceback.format_exc(), cmd=clean_args)
# Restore env settings

@ -25,9 +25,12 @@
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import json
from ansible.module_utils.urls import fetch_url
class Response(object):
def __init__(self, resp, info):

@ -25,27 +25,29 @@
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
import signal
import socket
import struct
import signal
from ansible.module_utils.basic import get_exception
from ansible.module_utils._text import to_bytes, to_native
def send_data(s, data):
packed_len = struct.pack('!Q',len(data))
packed_len = struct.pack('!Q', len(data))
return s.sendall(packed_len + data)
def recv_data(s):
header_len = 8 # size of a packed unsigned long long
header_len = 8 # size of a packed unsigned long long
data = to_bytes("")
while len(data) < header_len:
d = s.recv(header_len - len(data))
if not d:
return None
data += d
data_len = struct.unpack('!Q',data[:header_len])[0]
data_len = struct.unpack('!Q', data[:header_len])[0]
data = data[header_len:]
while len(data) < data_len:
d = s.recv(data_len - len(data))
@ -54,6 +56,7 @@ def recv_data(s):
data += d
return data
def exec_command(module, command):
try:
sf = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)

@ -26,9 +26,11 @@
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
class SQLParseError(Exception):
pass
class UnclosedQuoteError(SQLParseError):
pass
@ -38,6 +40,7 @@ class UnclosedQuoteError(SQLParseError):
_PG_IDENTIFIER_TO_DOT_LEVEL = dict(database=1, schema=2, table=3, column=4, role=1)
_MYSQL_IDENTIFIER_TO_DOT_LEVEL = dict(database=1, table=2, column=3, role=1, vars=1)
def _find_end_quote(identifier, quote_char):
accumulate = 0
while True:
@ -47,12 +50,12 @@ def _find_end_quote(identifier, quote_char):
raise UnclosedQuoteError
accumulate = accumulate + quote
try:
next_char = identifier[quote+1]
next_char = identifier[quote + 1]
except IndexError:
return accumulate
if next_char == quote_char:
try:
identifier = identifier[quote+2:]
identifier = identifier[quote + 2:]
accumulate = accumulate + 2
except IndexError:
raise UnclosedQuoteError
@ -73,10 +76,10 @@ def _identifier_parse(identifier, quote_char):
already_quoted = False
else:
if end_quote < len(identifier) - 1:
if identifier[end_quote+1] == '.':
if identifier[end_quote + 1] == '.':
dot = end_quote + 1
first_identifier = identifier[:dot]
next_identifier = identifier[dot+1:]
next_identifier = identifier[dot + 1:]
further_identifiers = _identifier_parse(next_identifier, quote_char)
further_identifiers.insert(0, first_identifier)
else:
@ -88,19 +91,19 @@ def _identifier_parse(identifier, quote_char):
try:
dot = identifier.index('.')
except ValueError:
identifier = identifier.replace(quote_char, quote_char*2)
identifier = identifier.replace(quote_char, quote_char * 2)
identifier = ''.join((quote_char, identifier, quote_char))
further_identifiers = [identifier]
else:
if dot == 0 or dot >= len(identifier) - 1:
identifier = identifier.replace(quote_char, quote_char*2)
identifier = identifier.replace(quote_char, quote_char * 2)
identifier = ''.join((quote_char, identifier, quote_char))
further_identifiers = [identifier]
else:
first_identifier = identifier[:dot]
next_identifier = identifier[dot+1:]
next_identifier = identifier[dot + 1:]
further_identifiers = _identifier_parse(next_identifier, quote_char)
first_identifier = first_identifier.replace(quote_char, quote_char*2)
first_identifier = first_identifier.replace(quote_char, quote_char * 2)
first_identifier = ''.join((quote_char, first_identifier, quote_char))
further_identifiers.insert(0, first_identifier)
@ -113,6 +116,7 @@ def pg_quote_identifier(identifier, id_type):
raise SQLParseError('PostgreSQL does not support %s with more than %i dots' % (id_type, _PG_IDENTIFIER_TO_DOT_LEVEL[id_type]))
return '.'.join(identifier_fragments)
def mysql_quote_identifier(identifier, id_type):
identifier_fragments = _identifier_parse(identifier, quote_char='`')
if len(identifier_fragments) > _MYSQL_IDENTIFIER_TO_DOT_LEVEL[id_type]:

@ -217,7 +217,7 @@ class AnsibleDockerClient(Client):
docker_host=self._get_value('docker_host', params['docker_host'], 'DOCKER_HOST',
DEFAULT_DOCKER_HOST),
tls_hostname=self._get_value('tls_hostname', params['tls_hostname'],
'DOCKER_TLS_HOSTNAME', 'localhost'),
'DOCKER_TLS_HOSTNAME', 'localhost'),
api_version=self._get_value('api_version', params['api_version'], 'DOCKER_API_VERSION',
'auto'),
cacert_path=self._get_value('cacert_path', params['cacert_path'], 'DOCKER_CERT_PATH', None),
@ -244,7 +244,7 @@ class AnsibleDockerClient(Client):
def _get_tls_config(self, **kwargs):
self.log("get_tls_config:")
for key in kwargs:
self.log(" %s: %s" % (key, kwargs[key]))
self.log(" %s: %s" % (key, kwargs[key]))
try:
tls_config = TLSConfig(**kwargs)
return tls_config
@ -327,11 +327,10 @@ class AnsibleDockerClient(Client):
def _handle_ssl_error(self, error):
match = re.match(r"hostname.*doesn\'t match (\'.*\')", str(error))
if match:
msg = "You asked for verification that Docker host name matches %s. The actual hostname is %s. " \
"Most likely you need to set DOCKER_TLS_HOSTNAME or pass tls_hostname with a value of %s. " \
"You may also use TLS without verification by setting the tls parameter to true." \
% (self.auth_params['tls_hostname'], match.group(1), match.group(1))
self.fail(msg)
self.fail("You asked for verification that Docker host name matches %s. The actual hostname is %s. "
"Most likely you need to set DOCKER_TLS_HOSTNAME or pass tls_hostname with a value of %s. "
"You may also use TLS without verification by setting the tls parameter to true."
% (self.auth_params['tls_hostname'], match.group(1), match.group(1)))
self.fail("SSL Exception: %s" % (error))
def get_container(self, name=None):
@ -448,5 +447,3 @@ class AnsibleDockerClient(Client):
new_tag = self.find_image(name, tag)
return new_tag, old_tag == new_tag

@ -34,7 +34,7 @@ from ansible.module_utils.cloud import CloudRetry
try:
import boto
import boto.ec2 #boto does weird import stuff
import boto.ec2 # boto does weird import stuff
HAS_BOTO = True
except ImportError:
HAS_BOTO = False
@ -54,6 +54,7 @@ except:
from ansible.module_utils.six import string_types, binary_type, text_type
class AnsibleAWSError(Exception):
pass
@ -98,6 +99,7 @@ def boto3_conn(module, conn_type=None, resource=None, region=None, endpoint=None
module.fail_json(msg='There is an issue in the code of the module. You must specify either both, resource or client to the conn_type '
'parameter in the boto3_conn function call')
def _boto3_conn(conn_type=None, resource=None, region=None, endpoint=None, **params):
profile = params.pop('profile_name', None)
@ -120,6 +122,7 @@ def _boto3_conn(conn_type=None, resource=None, region=None, endpoint=None, **par
boto3_inventory_conn = _boto3_conn
def aws_common_argument_spec():
return dict(
ec2_url=dict(),
@ -291,6 +294,7 @@ def ec2_connect(module):
return ec2
def paging(pause=0, marker_property='marker'):
""" Adds paging to boto retrieval functions that support a 'marker'
this is configurable as not all boto functions seem to use the
@ -330,7 +334,6 @@ def camel_dict_to_snake_dict(camel_dict):
return all_cap_re.sub(r'\1_\2', s1).lower()
def value_is_list(camel_list):
checked_list = []
@ -344,7 +347,6 @@ def camel_dict_to_snake_dict(camel_dict):
return checked_list
snake_dict = {}
for k, v in camel_dict.items():
if isinstance(v, dict):
@ -403,7 +405,7 @@ def ansible_dict_to_boto3_filter_list(filters_dict):
"""
filters_list = []
for k,v in filters_dict.items():
for k, v in filters_dict.items():
filter_dict = {'Name': k}
if isinstance(v, string_types):
filter_dict['Values'] = [v]
@ -470,7 +472,7 @@ def ansible_dict_to_boto3_tag_list(tags_dict, tag_name_key_name='Key', tag_value
"""
tags_list = []
for k,v in tags_dict.items():
for k, v in tags_dict.items():
tags_list.append({tag_name_key_name: k, tag_value_key_name: v})
return tags_list
@ -491,7 +493,6 @@ def get_ec2_security_group_ids_from_names(sec_group_list, ec2_connection, vpc_id
else:
return sg.name
def get_sg_id(sg, boto3):
if boto3:
@ -520,7 +521,7 @@ def get_ec2_security_group_ids_from_names(sec_group_list, ec2_connection, vpc_id
all_sec_groups = ec2_connection.describe_security_groups()['SecurityGroups']
else:
if vpc_id:
filters = { 'vpc-id': vpc_id }
filters = {'vpc-id': vpc_id}
all_sec_groups = ec2_connection.get_all_security_groups(filters=filters)
else:
all_sec_groups = ec2_connection.get_all_security_groups()
@ -536,7 +537,7 @@ def get_ec2_security_group_ids_from_names(sec_group_list, ec2_connection, vpc_id
if len(still_unmatched) > 0:
raise ValueError("The following group names are not valid: %s" % ', '.join(still_unmatched))
sec_group_id_list += [ str(get_sg_id(all_sg, boto3)) for all_sg in all_sec_groups if str(get_sg_name(all_sg, boto3)) in sec_group_name_list ]
sec_group_id_list += [str(get_sg_id(all_sg, boto3)) for all_sg in all_sec_groups if str(get_sg_name(all_sg, boto3)) in sec_group_name_list]
return sec_group_id_list

@ -56,7 +56,6 @@ def f5_argument_spec():
server_port=dict(
type='int',
default=443,
required=False,
fallback=(env_fallback, ['F5_SERVER_PORT'])
),
state=dict(
@ -80,7 +79,7 @@ def f5_parse_arguments(module):
import ssl
if not hasattr(ssl, 'SSLContext'):
module.fail_json(
msg="bigsuds does not support verifying certificates with python < 2.7.9." \
msg="bigsuds does not support verifying certificates with python < 2.7.9."
"Either update python or set validate_certs=False on the task'")
return (
@ -122,26 +121,22 @@ def bigip_api(bigip, user, password, validate_certs, port=443):
# Fully Qualified name (with the partition)
def fq_name(partition,name):
def fq_name(partition, name):
if name is not None and not name.startswith('/'):
return '/%s/%s' % (partition,name)
return '/%s/%s' % (partition, name)
return name
# Fully Qualified name (with partition) for a list
def fq_list_names(partition,list_names):
def fq_list_names(partition, list_names):
if list_names is None:
return None
return map(lambda x: fq_name(partition,x),list_names)
return map(lambda x: fq_name(partition, x), list_names)
# New style
from abc import ABCMeta, abstractproperty
from ansible.module_utils.six import with_metaclass
from collections import defaultdict
try:
@ -158,7 +153,7 @@ except ImportError:
from ansible.module_utils.basic import *
from ansible.module_utils.six import iteritems
from ansible.module_utils.six import iteritems, with_metaclass
F5_COMMON_ARGS = dict(
@ -187,7 +182,6 @@ F5_COMMON_ARGS = dict(
server_port=dict(
type='int',
default=443,
required=False,
fallback=(env_fallback, ['F5_SERVER_PORT'])
),
state=dict(
@ -286,7 +280,7 @@ class AnsibleF5Parameters(object):
def __init__(self, params=None):
self._values = defaultdict(lambda: None)
if params:
for k,v in iteritems(params):
for k, v in iteritems(params):
if self.api_map is not None and k in self.api_map:
dict_to_use = self.api_map
map_key = self.api_map[k]

@ -33,31 +33,31 @@ from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.pycompat24 import get_exception
#check for pyFG lib
# check for pyFG lib
try:
from pyFG import FortiOS, FortiConfig
from pyFG.exceptions import CommandExecutionException, FailedCommit
HAS_PYFG=True
HAS_PYFG = True
except ImportError:
HAS_PYFG=False
HAS_PYFG = False
fortios_argument_spec = dict(
file_mode = dict(type='bool', default=False),
config_file = dict(type='path'),
host = dict( ),
username = dict( ),
password = dict(type='str', no_log=True ),
timeout = dict(type='int', default=60),
vdom = dict(type='str', default=None ),
backup = dict(type='bool', default=False),
backup_path = dict(type='path'),
backup_filename = dict(type='str'),
file_mode=dict(type='bool', default=False),
config_file=dict(type='path'),
host=dict(),
username=dict(),
password=dict(type='str', no_log=True),
timeout=dict(type='int', default=60),
vdom=dict(type='str'),
backup=dict(type='bool', default=False),
backup_path=dict(type='path'),
backup_filename=dict(type='str'),
)
fortios_required_if = [
['file_mode', False, ['host', 'username', 'password']],
['file_mode', True, ['config_file']],
['backup', True , ['backup_path'] ],
['backup', True, ['backup_path']],
]
fortios_mutually_exclusive = [
@ -67,12 +67,12 @@ fortios_mutually_exclusive = [
]
fortios_error_codes = {
'-3':"Object not found",
'-61':"Command error"
'-3': "Object not found",
'-61': "Command error"
}
def backup(module,running_config):
def backup(module, running_config):
backup_path = module.params['backup_path']
backup_filename = module.params['backup_filename']
if not os.path.exists(backup_path):
@ -91,8 +91,6 @@ def backup(module,running_config):
module.fail_json(msg="Can't create backup file {0} Permission denied ?".format(filename))
class AnsibleFortios(object):
def __init__(self, module):
if not HAS_PYFG:
@ -103,7 +101,6 @@ class AnsibleFortios(object):
}
self.module = module
def _connect(self):
if self.module.params['file_mode']:
self.forti_device = FortiOS('')
@ -122,11 +119,10 @@ class AnsibleFortios(object):
e = get_exception()
self.module.fail_json(msg='Error connecting device. %s' % e)
def load_config(self, path):
self.path = path
self._connect()
#load in file_mode
# load in file_mode
if self.module.params['file_mode']:
try:
f = open(self.module.params['config_file'], 'r')
@ -135,10 +131,10 @@ class AnsibleFortios(object):
except IOError:
e = get_exception()
self.module.fail_json(msg='Error reading configuration file. %s' % e)
self.forti_device.load_config(config_text=running, path = path)
self.forti_device.load_config(config_text=running, path=path)
else:
#get config
# get config
try:
self.forti_device.load_config(path=path)
except Exception:
@ -146,22 +142,21 @@ class AnsibleFortios(object):
e = get_exception()
self.module.fail_json(msg='Error reading running config. %s' % e)
#set configs in object
# set configs in object
self.result['running_config'] = self.forti_device.running_config.to_text()
self.candidate_config = self.forti_device.candidate_config
#backup if needed
# backup if needed
if self.module.params['backup']:
backup(self.module, self.forti_device.running_config.to_text())
def apply_changes(self):
change_string = self.forti_device.compare_config()
if change_string:
self.result['change_string'] = change_string
self.result['changed'] = True
#Commit if not check mode
# Commit if not check mode
if change_string and not self.module.check_mode:
if self.module.params['file_mode']:
try:
@ -175,35 +170,31 @@ class AnsibleFortios(object):
try:
self.forti_device.commit()
except FailedCommit:
#Something's wrong (rollback is automatic)
# Something's wrong (rollback is automatic)
self.forti_device.close()
e = get_exception()
error_list = self.get_error_infos(e)
self.module.fail_json(msg_error_list=error_list, msg="Unable to commit change, check your args, the error was %s" % e.message )
self.module.fail_json(msg_error_list=error_list, msg="Unable to commit change, check your args, the error was %s" % e.message)
self.forti_device.close()
self.module.exit_json(**self.result)
def del_block(self, block_id):
self.forti_device.candidate_config[self.path].del_block(block_id)
def add_block(self, block_id, block):
self.forti_device.candidate_config[self.path][block_id] = block
def get_error_infos(self, cli_errors):
error_list = []
for errors in cli_errors.args:
for error in errors:
error_code = error[0]
error_string = error[1]
error_type = fortios_error_codes.get(error_code,"unknown")
error_list.append(dict(error_code=error_code, error_type=error_type, error_string= error_string))
error_type = fortios_error_codes.get(error_code, "unknown")
error_list.append(dict(error_code=error_code, error_type=error_type, error_string=error_string))
return error_list
def get_empty_configuration_block(self, block_name, block_type):
return FortiConfig(block_name, block_type)

@ -27,9 +27,6 @@
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
from ansible.module_utils.gcp import gcp_connect
from ansible.module_utils.gcp import unexpected_error_msg as gcp_error
try:
from libcloud.dns.types import Provider
from libcloud.dns.providers import get_driver
@ -37,9 +34,13 @@ try:
except ImportError:
HAS_LIBCLOUD_BASE = False
from ansible.module_utils.gcp import gcp_connect
from ansible.module_utils.gcp import unexpected_error_msg as gcp_error
USER_AGENT_PRODUCT = "Ansible-gcdns"
USER_AGENT_VERSION = "v1"
def gcdns_connect(module, provider=None):
"""Return a GCP connection for Google Cloud DNS."""
if not HAS_LIBCLOUD_BASE:
@ -48,6 +49,7 @@ def gcdns_connect(module, provider=None):
provider = provider or Provider.GOOGLE
return gcp_connect(module, provider, get_driver, USER_AGENT_PRODUCT, USER_AGENT_VERSION)
def unexpected_error_msg(error):
"""Create an error string based on passed in error."""
return gcp_error(error)

@ -25,10 +25,6 @@
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
from ansible.module_utils.gcp import gcp_connect
from ansible.module_utils.gcp import unexpected_error_msg as gcp_error
try:
from libcloud.compute.types import Provider
@ -37,9 +33,13 @@ try:
except ImportError:
HAS_LIBCLOUD_BASE = False
from ansible.module_utils.gcp import gcp_connect
from ansible.module_utils.gcp import unexpected_error_msg as gcp_error
USER_AGENT_PRODUCT = "Ansible-gce"
USER_AGENT_VERSION = "v1"
def gce_connect(module, provider=None):
"""Return a GCP connection for Google Compute Engine."""
if not HAS_LIBCLOUD_BASE:
@ -48,6 +48,7 @@ def gce_connect(module, provider=None):
return gcp_connect(module, provider, get_driver, USER_AGENT_PRODUCT, USER_AGENT_VERSION)
def unexpected_error_msg(error):
"""Create an error string based on passed in error."""
return gcp_error(error)

@ -502,8 +502,7 @@ class GCPUtils(object):
@staticmethod
def underscore_to_camel(txt):
return txt.split('_')[0] + ''.join(x.capitalize()
or '_' for x in txt.split('_')[1:])
return txt.split('_')[0] + ''.join(x.capitalize() or '_' for x in txt.split('_')[1:])
@staticmethod
def remove_non_gcp_params(params):
@ -626,7 +625,7 @@ class GCPUtils(object):
# TODO(supertom): Isolate 'build-new-request' stuff.
resource_name_singular = GCPUtils.get_entity_name_from_resource_name(
resource_name)
if op_resp['operationType'] == 'insert' or not 'entity_name' in parsed_url:
if op_resp['operationType'] == 'insert' or 'entity_name' not in parsed_url:
parsed_url['entity_name'] = GCPUtils.parse_gcp_url(op_resp['targetLink'])[
'entity_name']
args = {'project': project_id,

@ -82,9 +82,9 @@ def infinibox_argument_spec():
"""Return standard base dictionary used for the argument_spec argument in AnsibleModule"""
return dict(
system = dict(required=True),
user = dict(),
password = dict(no_log=True),
system=dict(required=True),
user=dict(),
password=dict(no_log=True),
)

@ -29,6 +29,7 @@ try:
except ImportError:
import simplejson as json
# NB: a copy of this function exists in ../../modules/core/async_wrapper.py. Ensure any
# changes are propagated there.
def _filter_non_json_lines(data):

@ -47,12 +47,13 @@ ARGS_DEFAULT_VALUE = {
'timeout': 10
}
def check_args(module, warnings):
provider = module.params['provider'] or {}
for key in junos_argument_spec:
if key not in ('provider',) and module.params[key]:
warnings.append('argument %s has been deprecated and will be '
'removed in a future version' % key)
'removed in a future version' % key)
# set argument's default value if not provided in input
# This is done to avoid unwanted argument deprecation warning
@ -66,6 +67,7 @@ def check_args(module, warnings):
if provider.get(param):
module.no_log_values.update(return_values(provider[param]))
def _validate_rollback_id(module, value):
try:
if not 0 <= int(value) <= 49:
@ -73,6 +75,7 @@ def _validate_rollback_id(module, value):
except ValueError:
module.fail_json(msg='rollback must be between 0 and 49')
def load_configuration(module, candidate=None, action='merge', rollback=None, format='xml'):
if all((candidate is None, rollback is None)):
@ -117,6 +120,7 @@ def load_configuration(module, candidate=None, action='merge', rollback=None, fo
cfg.append(candidate)
return send_request(module, obj)
def get_configuration(module, compare=False, format='xml', rollback='0'):
if format not in CONFIG_FORMATS:
module.fail_json(msg='invalid config format specified')
@ -127,6 +131,7 @@ def get_configuration(module, compare=False, format='xml', rollback='0'):
xattrs['rollback'] = str(rollback)
return send_request(module, Element('get-configuration', xattrs))
def commit_configuration(module, confirm=False, check=False, comment=None, confirm_timeout=None):
obj = Element('commit-configuration')
if confirm:
@ -141,6 +146,7 @@ def commit_configuration(module, confirm=False, check=False, comment=None, confi
subele.text = str(confirm_timeout)
return send_request(module, obj)
def command(module, command, format='text', rpc_only=False):
xattrs = {'format': format}
if rpc_only:
@ -148,8 +154,14 @@ def command(module, command, format='text', rpc_only=False):
xattrs['format'] = 'text'
return send_request(module, Element('command', xattrs, text=command))
lock_configuration = lambda x: send_request(x, Element('lock-configuration'))
unlock_configuration = lambda x: send_request(x, Element('unlock-configuration'))
def lock_configuration(x):
return send_request(x, Element('lock-configuration'))
def unlock_configuration(x):
return send_request(x, Element('unlock-configuration'))
@contextmanager
def locked_config(module):
@ -159,6 +171,7 @@ def locked_config(module):
finally:
unlock_configuration(module)
def get_diff(module):
reply = get_configuration(module, compare=True, format='text')
@ -166,6 +179,7 @@ def get_diff(module):
if output is not None:
return to_text(output.text, encoding='latin1').strip()
def load_config(module, candidate, warnings, action='merge', commit=False, format='xml',
comment=None, confirm=False, confirm_timeout=None):
@ -192,5 +206,6 @@ def load_config(module, candidate, warnings, action='merge', commit=False, forma
return diff
def get_param(module, key):
return module.params[key] or module.params['provider'].get(key)

@ -153,7 +153,7 @@ def not_in_host_file(self, host):
if tokens[0].find(HASHED_KEY_MAGIC) == 0:
# this is a hashed known host entry
try:
(kn_salt,kn_host) = tokens[0][len(HASHED_KEY_MAGIC):].split("|",2)
(kn_salt, kn_host) = tokens[0][len(HASHED_KEY_MAGIC):].split("|", 2)
hash = hmac.new(kn_salt.decode('base64'), digestmod=sha1)
hash.update(host)
if hash.digest() == kn_host.decode('base64'):
@ -204,7 +204,7 @@ def add_host_key(module, fqdn, port=22, key_type="rsa", create_dir=False):
if rc != 0 or not out:
msg = 'failed to retrieve hostkey'
if not out:
msg += '. "%s" returned no matches.' % this_cmd
msg += '. "%s" returned no matches.' % this_cmd
else:
msg += ' using command "%s". [stdout]: %s' % (this_cmd, out)

@ -38,12 +38,14 @@ except ImportError:
# httplib/http.client connection using unix domain socket
import socket
import ssl
try:
from httplib import HTTPConnection, HTTPSConnection
except ImportError:
# Python 3
from http.client import HTTPConnection, HTTPSConnection
class UnixHTTPConnection(HTTPConnection):
def __init__(self, path):
HTTPConnection.__init__(self, 'localhost')
@ -54,11 +56,13 @@ class UnixHTTPConnection(HTTPConnection):
sock.connect(self.path)
self.sock = sock
class LXDClientException(Exception):
def __init__(self, msg, **kwargs):
self.msg = msg
self.kwargs = kwargs
class LXDClient(object):
def __init__(self, url, key_file=None, cert_file=None, debug=False):
"""LXD Client.

@ -35,6 +35,7 @@ try:
except ImportError:
mysqldb_found = False
def mysql_connect(module, login_user=None, login_password=None, config_file='', ssl_cert=None, ssl_key=None, ssl_ca=None, db=None, cursor_class=None,
connect_timeout=30):
config = {}

@ -92,13 +92,20 @@ class ConfigLine(object):
assert isinstance(obj, ConfigLine), 'child must be of type `ConfigLine`'
self._children.append(obj)
def ignore_line(text, tokens=None):
for item in (tokens or DEFAULT_COMMENT_TOKENS):
if text.startswith(item):
return True
_obj_to_text = lambda x: [o.text for o in x]
_obj_to_raw = lambda x: [o.raw for o in x]
def _obj_to_text(x):
return [o.text for o in x]
def _obj_to_raw(x):
return [o.raw for o in x]
def _obj_to_block(objects, visited=None):
items = list()
@ -110,6 +117,7 @@ def _obj_to_block(objects, visited=None):
items.append(child)
return _obj_to_raw(items)
def dumps(objects, output='block', comments=False):
if output == 'block':
items = _obj_to_block(objects)
@ -130,6 +138,7 @@ def dumps(objects, output='block', comments=False):
return '\n'.join(items)
class NetworkConfig(object):
def __init__(self, indent=1, contents=None):
@ -328,7 +337,7 @@ class NetworkConfig(object):
offset = 0
obj = None
## global config command
# global config command
if not parents:
for line in lines:
item = ConfigLine(line)

@ -24,17 +24,16 @@
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
import re
import time
import shlex
import time
from ansible.module_utils.basic import BOOLEANS_TRUE, BOOLEANS_FALSE
from ansible.module_utils.basic import get_exception
from ansible.module_utils.basic import BOOLEANS_TRUE, BOOLEANS_FALSE, get_exception
from ansible.module_utils.six import string_types, text_type
from ansible.module_utils.six.moves import zip
def to_list(val):
if isinstance(val, (list, tuple)):
return list(val)
@ -49,20 +48,23 @@ class FailedConditionsError(Exception):
super(FailedConditionsError, self).__init__(msg)
self.failed_conditions = failed_conditions
class FailedConditionalError(Exception):
def __init__(self, msg, failed_conditional):
super(FailedConditionalError, self).__init__(msg)
self.failed_conditional = failed_conditional
class AddCommandError(Exception):
def __init__(self, msg, command):
super(AddCommandError, self).__init__(msg)
self.command = command
class AddConditionError(Exception):
def __init__(self, msg, condition):
super(AddConditionError, self).__init__(msg)
self.condition=condition
self.condition = condition
class Cli(object):
@ -105,6 +107,7 @@ class Cli(object):
return responses
class Command(object):
def __init__(self, command, output=None, prompt=None, response=None,
@ -122,6 +125,7 @@ class Command(object):
def __str__(self):
return self.command_string
class CommandRunner(object):
def __init__(self, module):

@ -26,14 +26,13 @@
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
from contextlib import contextmanager
from xml.etree.ElementTree import Element, SubElement
from xml.etree.ElementTree import tostring, fromstring
from xml.etree.ElementTree import Element, SubElement, fromstring, tostring
from ansible.module_utils.connection import exec_command
NS_MAP = {'nc': "urn:ietf:params:xml:ns:netconf:base:1.0"}
def send_request(module, obj, check_rc=True):
request = tostring(obj)
rc, out, err = exec_command(module, request)
@ -58,6 +57,7 @@ def send_request(module, obj, check_rc=True):
return warnings
return fromstring(out)
def children(root, iterable):
for item in iterable:
try:
@ -65,33 +65,40 @@ def children(root, iterable):
except NameError:
ele = SubElement(root, item)
def lock(module, target='candidate'):
obj = Element('lock')
children(obj, ('target', target))
return send_request(module, obj)
def unlock(module, target='candidate'):
obj = Element('unlock')
children(obj, ('target', target))
return send_request(module, obj)
def commit(module):
return send_request(module, Element('commit'))
def discard_changes(module):
return send_request(module, Element('discard-changes'))
def validate(module):
obj = Element('validate')
children(obj, ('source', 'candidate'))
return send_request(module, obj)
def get_config(module, source='running', filter=None):
obj = Element('get-config')
children(obj, ('source', source))
children(obj, ('filter', filter))
return send_request(module, obj)
@contextmanager
def locked_config(module):
try:

@ -52,6 +52,7 @@ NET_CONNECTION_ARGS = dict()
NET_CONNECTIONS = dict()
def _transitional_argument_spec():
argument_spec = {}
for key, value in iteritems(NET_TRANSPORT_ARGS):
@ -59,6 +60,7 @@ def _transitional_argument_spec():
argument_spec[key] = value
return argument_spec
def to_list(val):
if isinstance(val, (list, tuple)):
return list(val)
@ -75,12 +77,14 @@ class ModuleStub(object):
self.params[key] = value.get('default')
self.fail_json = fail_json
class NetworkError(Exception):
def __init__(self, msg, **kwargs):
super(NetworkError, self).__init__(msg)
self.kwargs = kwargs
class Config(object):
def __init__(self, connection):
@ -185,6 +189,7 @@ class NetworkModule(AnsibleModule):
exc = get_exception()
self.fail_json(msg=to_native(exc))
def register_transport(transport, default=False):
def register(cls):
NET_CONNECTIONS[transport] = cls
@ -193,6 +198,6 @@ def register_transport(transport, default=False):
return cls
return register
def add_argument(key, value):
NET_CONNECTION_ARGS[key] = value

@ -24,9 +24,10 @@
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
from ansible.module_utils.six import iteritems
from ansible.module_utils.basic import AnsibleFallbackNotFound
from ansible.module_utils.six import iteritems
def to_list(val):
if isinstance(val, (list, tuple, set)):
@ -36,6 +37,7 @@ def to_list(val):
else:
return list()
class ComplexDict(object):
"""Transforms a dict to with an argument spec
@ -77,7 +79,7 @@ class ComplexDict(object):
if attr.get('read_from'):
spec = self._module.argument_spec.get(attr['read_from'])
if not spec:
raise ValueError('argument_spec %s does not exist' % attr['read_from'])
raise ValueError('argument_spec %s does not exist' % attr['read_from'])
for key, value in iteritems(spec):
if key not in attr:
attr[key] = value
@ -88,7 +90,6 @@ class ComplexDict(object):
self_has_key = True
attr['required'] = True
def _dict(self, value):
obj = {}
for name, attr in iteritems(self._attributes):
@ -131,8 +132,7 @@ class ComplexDict(object):
if 'choices' in attr:
if value[name] not in attr['choices']:
raise ValueError('%s must be one of %s, got %s' % \
(name, ', '.join(attr['choices']), value[name]))
raise ValueError('%s must be one of %s, got %s' % (name, ', '.join(attr['choices']), value[name]))
if value[name] is not None:
value_type = attr.get('type', 'str')
@ -141,6 +141,7 @@ class ComplexDict(object):
return value
class ComplexList(ComplexDict):
"""Extends ```ComplexDict``` to handle a list of dicts """
@ -148,4 +149,3 @@ class ComplexList(ComplexDict):
if not isinstance(values, (list, tuple)):
raise TypeError('value must be an ordered iterable')
return [(super(ComplexList, self).__call__(v)) for v in values]

@ -30,6 +30,7 @@ import os
from ansible.module_utils.six import iteritems
def openstack_argument_spec():
# DEPRECATED: This argument spec is only used for the deprecated old
# OpenStack modules. It turns out that modern OpenStack auth is WAY
@ -37,17 +38,17 @@ def openstack_argument_spec():
# Consume standard OpenStack environment variables.
# This is mainly only useful for ad-hoc command line operation as
# in playbooks one would assume variables would be used appropriately
OS_AUTH_URL=os.environ.get('OS_AUTH_URL', 'http://127.0.0.1:35357/v2.0/')
OS_PASSWORD=os.environ.get('OS_PASSWORD', None)
OS_REGION_NAME=os.environ.get('OS_REGION_NAME', None)
OS_USERNAME=os.environ.get('OS_USERNAME', 'admin')
OS_TENANT_NAME=os.environ.get('OS_TENANT_NAME', OS_USERNAME)
OS_AUTH_URL = os.environ.get('OS_AUTH_URL', 'http://127.0.0.1:35357/v2.0/')
OS_PASSWORD = os.environ.get('OS_PASSWORD', None)
OS_REGION_NAME = os.environ.get('OS_REGION_NAME', None)
OS_USERNAME = os.environ.get('OS_USERNAME', 'admin')
OS_TENANT_NAME = os.environ.get('OS_TENANT_NAME', OS_USERNAME)
spec = dict(
login_username = dict(default=OS_USERNAME),
auth_url = dict(default=OS_AUTH_URL),
region_name = dict(default=OS_REGION_NAME),
availability_zone = dict(default=None),
login_username=dict(default=OS_USERNAME),
auth_url=dict(default=OS_AUTH_URL),
region_name=dict(default=OS_REGION_NAME),
availability_zone=dict(),
)
if OS_PASSWORD:
spec['login_password'] = dict(default=OS_PASSWORD)
@ -59,6 +60,7 @@ def openstack_argument_spec():
spec['login_tenant_name'] = dict(required=True)
return spec
def openstack_find_nova_addresses(addresses, ext_tag, key_name=None):
ret = []
@ -71,6 +73,7 @@ def openstack_find_nova_addresses(addresses, ext_tag, key_name=None):
ret.append(interface_spec['addr'])
return ret
def openstack_full_argument_spec(**kwargs):
spec = dict(
cloud=dict(default=None),

@ -37,6 +37,7 @@ from ansible.module_utils.urls import fetch_url, url_argument_spec
add_argument('use_ssl', dict(default=True, type='bool'))
add_argument('validate_certs', dict(default=True, type='bool'))
def get_opsidl():
extschema = restparser.parseSchema(settings.get('ext_schema'))
ovsschema = settings.get('ovs_schema')
@ -129,7 +130,7 @@ class Rest(object):
def authorize(self, params, **kwargs):
raise NotImplementedError
### REST methods ###
# REST methods
def _url_builder(self, path):
if path[0] == '/':
@ -160,12 +161,12 @@ class Rest(object):
def delete(self, path, data=None, headers=None):
return self.request('DELETE', path, data, headers)
### Command methods ###
# Command methods
def run_commands(self, commands):
raise NotImplementedError
### Config methods ###
# Config methods
def configure(self, commands):
path = '/system/full-configuration'
@ -212,7 +213,7 @@ class Cli(CliBase):
NET_PASSWD_RE = re.compile(r"[\r\n]?password: $", re.I)
### Config methods ###
# Config methods
def configure(self, commands, **kwargs):
cmds = ['configure terminal']

@ -1,5 +1,6 @@
_DEVICE_CONFIGS = {}
def get_config(module, flags=[]):
cmd = 'show running-config '
cmd += ' '.join(flags)

@ -504,7 +504,6 @@ class BaseModule(object):
after[k] = update[k]
return after
def create(
self,
entity=None,
@ -579,9 +578,14 @@ class BaseModule(object):
# Wait for the entity to be created and to be in the defined state:
entity_service = self._service.service(entity.id)
state_condition = lambda entity: entity
def state_condition(entity):
return entity
if result_state:
state_condition = lambda entity: entity and entity.status == result_state
def state_condition(entity):
return entity and entity.status == result_state
wait(
service=entity_service,
condition=state_condition,

@ -27,24 +27,21 @@
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# standard ansible imports
from ansible.module_utils.basic import get_exception
# standard PG imports
HAS_PSYCOPG2 = False
try:
import psycopg2
import psycopg2.extras
except ImportError:
pass
else:
HAS_PSYCOPG2 = True
except ImportError:
HAS_PSYCOPG2 = False
from ansible.module_utils.basic import get_exception
from ansible.module_utils.six import iteritems
class LibraryError(Exception):
pass
def ensure_libs(sslrootcert=None):
if not HAS_PSYCOPG2:
raise LibraryError('psycopg2 is not installed. we need psycopg2.')
@ -54,14 +51,14 @@ def ensure_libs(sslrootcert=None):
# no problems
return None
def postgres_common_argument_spec():
return dict(
login_user = dict(default='postgres'),
login_password = dict(default='', no_log=True),
login_host = dict(default=''),
login_unix_socket = dict(default=''),
port = dict(type='int', default=5432),
ssl_mode = dict(default='prefer', choices=['disable', 'allow', 'prefer', 'require', 'verify-ca', 'verify-full']),
ssl_rootcert = dict(default=None),
login_user=dict(default='postgres'),
login_password=dict(default='', no_log=True),
login_host=dict(default=''),
login_unix_socket=dict(default=''),
port=dict(type='int', default=5432),
ssl_mode=dict(default='prefer', choices=['disable', 'allow', 'prefer', 'require', 'verify-ca', 'verify-full']),
ssl_rootcert=dict(),
)

@ -25,10 +25,10 @@
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
import sys
def get_exception():
"""Get the current exception.

@ -125,9 +125,9 @@ class Rhsm(RegistrationBase):
# Pass supplied **kwargs as parameters to subscription-manager. Ignore
# non-configuration parameters and replace '_' with '.'. For example,
# 'server_hostname' becomes '--system.hostname'.
for k,v in kwargs.items():
for k, v in kwargs.items():
if re.search(r'^(system|rhsm)_', k):
args.append('--%s=%s' % (k.replace('_','.'), v))
args.append('--%s=%s' % (k.replace('_', '.'), v))
self.module.run_command(args, check_rc=True)
@ -213,7 +213,7 @@ class RhsmPool(object):
def __init__(self, module, **kwargs):
self.module = module
for k,v in kwargs.items():
for k, v in kwargs.items():
setattr(self, k, v)
def __str__(self):
@ -255,7 +255,7 @@ class RhsmPools(object):
continue
# If a colon ':' is found, parse
elif ':' in line:
(key, value) = line.split(':',1)
(key, value) = line.split(':', 1)
key = key.strip().replace(" ", "") # To unify
value = value.strip()
if key in ['ProductName', 'SubscriptionName']:
@ -265,7 +265,7 @@ class RhsmPools(object):
# Associate value with most recently recorded product
products[-1].__setattr__(key, value)
# FIXME - log some warning?
#else:
# else:
# warnings.warn("Unhandled subscription key/value: %s/%s" % (key,value))
return products
@ -277,4 +277,3 @@ class RhsmPools(object):
for product in self.products:
if r.search(product._name):
yield product

@ -25,20 +25,20 @@
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
import os
import shlex
import subprocess
import glob
import select
import os
import pickle
import platform
import select
import shlex
import subprocess
import traceback
from ansible.module_utils.six import PY2, b
from ansible.module_utils._text import to_bytes, to_text
def sysv_is_enabled(name):
'''
This function will check if the service name supplied
@ -48,6 +48,7 @@ def sysv_is_enabled(name):
'''
return bool(glob.glob('/etc/rc?.d/S??%s' % name))
def get_sysv_script(name):
'''
This function will return the expected path for an init script
@ -62,6 +63,7 @@ def get_sysv_script(name):
return result
def sysv_exists(name):
'''
This function will return True or False depending on
@ -71,6 +73,7 @@ def sysv_exists(name):
'''
return os.path.exists(get_sysv_script(name))
def fail_if_missing(module, found, service, msg=''):
'''
This function will return an error or exit gracefully depending on check mode status
@ -87,6 +90,7 @@ def fail_if_missing(module, found, service, msg=''):
else:
module.fail_json(msg='Could not find the requested service %s: %s' % (service, msg))
def daemonize(module, cmd):
'''
Execute a command while detaching as a deamon, returns rc, stdout, and stderr.
@ -100,10 +104,10 @@ def daemonize(module, cmd):
'''
# init some vars
chunk = 4096 #FIXME: pass in as arg?
chunk = 4096 # FIXME: pass in as arg?
errors = 'surrogate_or_strict'
#start it!
# start it!
try:
pipe = os.pipe()
pid = os.fork()
@ -162,7 +166,7 @@ def daemonize(module, cmd):
fds = [p.stdout, p.stderr]
# loop reading output till its done
output = { p.stdout: b(""), p.sterr: b("") }
output = {p.stdout: b(""), p.sterr: b("")}
while fds:
rfd, wfd, efd = select.select(fds, [], fds, 1)
if (rfd + wfd + efd) or p.poll():
@ -207,6 +211,7 @@ def daemonize(module, cmd):
# py2 and py3)
return pickle.loads(to_bytes(return_data, errors=errors))
def check_ps(module, pattern):
# Set ps flags

@ -281,5 +281,8 @@ class CliBase(object):
exc = get_exception()
raise NetworkError(to_native(exc))
run_commands = lambda self, x: self.execute(to_list(x))
exec_command = lambda self, x: self.shell.send(self.to_command(x))
def run_commands(self, x):
return self.execute(to_list(x))
def exec_command(self, x):
return self.shell.send(self.to_command(x))

@ -26,6 +26,7 @@
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
def _get_quote_state(token, quote_char):
'''
the goal of this block is to determine if the quoted string
@ -36,7 +37,7 @@ def _get_quote_state(token, quote_char):
prev_char = None
for idx, cur_char in enumerate(token):
if idx > 0:
prev_char = token[idx-1]
prev_char = token[idx - 1]
if cur_char in '"\'' and prev_char != '\\':
if quote_char:
if cur_char == quote_char:
@ -45,13 +46,14 @@ def _get_quote_state(token, quote_char):
quote_char = cur_char
return quote_char
def _count_jinja2_blocks(token, cur_depth, open_token, close_token):
'''
this function counts the number of opening/closing blocks for a
given opening/closing type and adjusts the current depth for that
block based on the difference
'''
num_open = token.count(open_token)
num_open = token.count(open_token)
num_close = token.count(close_token)
if num_open != num_close:
cur_depth += (num_open - num_close)
@ -59,6 +61,7 @@ def _count_jinja2_blocks(token, cur_depth, open_token, close_token):
cur_depth = 0
return cur_depth
def split_args(args):
'''
Splits args on whitespace, but intelligently reassembles
@ -99,13 +102,13 @@ def split_args(args):
quote_char = None
inside_quotes = False
print_depth = 0 # used to count nested jinja2 {{ }} blocks
block_depth = 0 # used to count nested jinja2 {% %} blocks
comment_depth = 0 # used to count nested jinja2 {# #} blocks
print_depth = 0 # used to count nested jinja2 {{ }} blocks
block_depth = 0 # used to count nested jinja2 {% %} blocks
comment_depth = 0 # used to count nested jinja2 {# #} blocks
# now we loop over each split chunk, coalescing tokens if the white space
# split occurred within quotes or a jinja2 block of some kind
for itemidx,item in enumerate(items):
for itemidx, item in enumerate(items):
# we split on spaces and newlines separately, so that we
# can tell which character we split on for reassembly
@ -113,7 +116,7 @@ def split_args(args):
tokens = item.strip().split(' ')
line_continuation = False
for idx,token in enumerate(tokens):
for idx, token in enumerate(tokens):
# if we hit a line continuation character, but
# we're not inside quotes, ignore it and continue
@ -201,12 +204,13 @@ def split_args(args):
return params
def is_quoted(data):
return len(data) > 0 and (data[0] == '"' and data[-1] == '"' or data[0] == "'" and data[-1] == "'")
def unquote(data):
''' removes first and last quotes from a string, if the string starts and ends with the same quotes '''
if is_quoted(data):
return data[1:-1]
return data

@ -105,20 +105,20 @@ def uldap():
def construct():
try:
secret_file = open('/etc/ldap.secret', 'r')
bind_dn = 'cn=admin,{}'.format(base_dn())
bind_dn = 'cn=admin,{}'.format(base_dn())
except IOError: # pragma: no cover
secret_file = open('/etc/machine.secret', 'r')
bind_dn = config_registry()["ldap/hostdn"]
pwd_line = secret_file.readline()
pwd = re.sub('\n', '', pwd_line)
bind_dn = config_registry()["ldap/hostdn"]
pwd_line = secret_file.readline()
pwd = re.sub('\n', '', pwd_line)
import univention.admin.uldap
return univention.admin.uldap.access(
host = config_registry()['ldap/master'],
base = base_dn(),
binddn = bind_dn,
bindpw = pwd,
start_tls = 1
host=config_registry()['ldap/master'],
base=base_dn(),
binddn=bind_dn,
bindpw=pwd,
start_tls=1,
)
return _singleton('uldap', construct)

@ -206,17 +206,14 @@ except ImportError:
HAS_MATCH_HOSTNAME = False
if not HAS_MATCH_HOSTNAME:
###
### The following block of code is under the terms and conditions of the
### Python Software Foundation License
###
# The following block of code is under the terms and conditions of the
# Python Software Foundation License
"""The match_hostname() function from Python 3.4, essential when using SSL."""
class CertificateError(ValueError):
pass
def _dnsname_match(dn, hostname, max_wildcards=1):
"""Matching according to RFC 6125, section 6.4.3
@ -269,7 +266,6 @@ if not HAS_MATCH_HOSTNAME:
pat = re.compile(r'\A' + r'\.'.join(pats) + r'\Z', re.IGNORECASE)
return pat.match(hostname)
def match_hostname(cert, hostname):
"""Verify that *cert* (in decoded format as returned by
SSLSocket.getpeercert()) matches the *hostname*. RFC 2818 and RFC 6125
@ -299,20 +295,13 @@ if not HAS_MATCH_HOSTNAME:
return
dnsnames.append(value)
if len(dnsnames) > 1:
raise CertificateError("hostname %r "
"doesn't match either of %s"
% (hostname, ', '.join(map(repr, dnsnames))))
raise CertificateError("hostname %r " "doesn't match either of %s" % (hostname, ', '.join(map(repr, dnsnames))))
elif len(dnsnames) == 1:
raise CertificateError("hostname %r "
"doesn't match %r"
% (hostname, dnsnames[0]))
raise CertificateError("hostname %r doesn't match %r" % (hostname, dnsnames[0]))
else:
raise CertificateError("no appropriate commonName or "
"subjectAltName fields were found")
raise CertificateError("no appropriate commonName or subjectAltName fields were found")
###
### End of Python Software Foundation Licensed code
###
# End of Python Software Foundation Licensed code
HAS_MATCH_HOSTNAME = True
@ -399,7 +388,7 @@ if hasattr(httplib, 'HTTPSConnection') and hasattr(urllib_request, 'HTTPSHandler
self.sock = self.context.wrap_socket(sock, server_hostname=server_hostname)
elif HAS_URLLIB3_SSL_WRAP_SOCKET:
self.sock = ssl_wrap_socket(sock, keyfile=self.key_file, cert_reqs=ssl.CERT_NONE, certfile=self.cert_file, ssl_version=PROTOCOL,
server_hostname=server_hostname)
server_hostname=server_hostname)
else:
self.sock = ssl.wrap_socket(sock, keyfile=self.key_file, certfile=self.cert_file, ssl_version=PROTOCOL)
@ -448,24 +437,24 @@ def generic_urlparse(parts):
if hasattr(parts, 'netloc'):
# urlparse is newer, just read the fields straight
# from the parts object
generic_parts['scheme'] = parts.scheme
generic_parts['netloc'] = parts.netloc
generic_parts['path'] = parts.path
generic_parts['params'] = parts.params
generic_parts['query'] = parts.query
generic_parts['scheme'] = parts.scheme
generic_parts['netloc'] = parts.netloc
generic_parts['path'] = parts.path
generic_parts['params'] = parts.params
generic_parts['query'] = parts.query
generic_parts['fragment'] = parts.fragment
generic_parts['username'] = parts.username
generic_parts['password'] = parts.password
generic_parts['hostname'] = parts.hostname
generic_parts['port'] = parts.port
generic_parts['port'] = parts.port
else:
# we have to use indexes, and then parse out
# the other parts not supported by indexing
generic_parts['scheme'] = parts[0]
generic_parts['netloc'] = parts[1]
generic_parts['path'] = parts[2]
generic_parts['params'] = parts[3]
generic_parts['query'] = parts[4]
generic_parts['scheme'] = parts[0]
generic_parts['netloc'] = parts[1]
generic_parts['path'] = parts[2]
generic_parts['params'] = parts[3]
generic_parts['query'] = parts[4]
generic_parts['fragment'] = parts[5]
# get the username, password, etc.
try:
@ -488,12 +477,12 @@ def generic_urlparse(parts):
generic_parts['username'] = username
generic_parts['password'] = password
generic_parts['hostname'] = hostname
generic_parts['port'] = port
generic_parts['port'] = port
except:
generic_parts['username'] = None
generic_parts['password'] = None
generic_parts['hostname'] = parts[1]
generic_parts['port'] = None
generic_parts['port'] = None
return generic_parts
@ -551,9 +540,8 @@ def RedirectHandlerFactory(follow_redirects=None, validate_certs=True):
if do_redirect:
# be conciliant with URIs containing a space
newurl = newurl.replace(' ', '%20')
newheaders = dict((k,v) for k,v in req.headers.items()
if k.lower() not in ("content-length", "content-type")
)
newheaders = dict((k, v) for k, v in req.headers.items()
if k.lower() not in ("content-length", "content-type"))
try:
# Python 2-3.3
origin_req_host = req.get_origin_req_host()
@ -561,9 +549,9 @@ def RedirectHandlerFactory(follow_redirects=None, validate_certs=True):
# Python 3.4+
origin_req_host = req.origin_req_host
return urllib_request.Request(newurl,
headers=newheaders,
origin_req_host=origin_req_host,
unverifiable=True)
headers=newheaders,
origin_req_host=origin_req_host,
unverifiable=True)
else:
raise urllib_error.HTTPError(req.get_full_url(), code, msg, hdrs, fp)
@ -660,7 +648,7 @@ class SSLValidationHandler(urllib_request.BaseHandler):
dir_contents = os.listdir(path)
for f in dir_contents:
full_path = os.path.join(path, f)
if os.path.isfile(full_path) and os.path.splitext(f)[1] in ('.crt','.pem'):
if os.path.isfile(full_path) and os.path.splitext(f)[1] in ('.crt', '.pem'):
try:
cert_file = open(full_path, 'rb')
cert = cert_file.read()
@ -738,7 +726,7 @@ class SSLValidationHandler(urllib_request.BaseHandler):
if proxy_parts.get('scheme') == 'http':
s.sendall(self.CONNECT_COMMAND % (self.hostname, self.port))
if proxy_parts.get('username'):
credentials = "%s:%s" % (proxy_parts.get('username',''), proxy_parts.get('password',''))
credentials = "%s:%s" % (proxy_parts.get('username', ''), proxy_parts.get('password', ''))
s.sendall(b('Proxy-Authorization: Basic %s\r\n') % base64.b64encode(to_bytes(credentials, errors='surrogate_or_strict')).strip())
s.sendall(b('\r\n'))
connect_result = b("")
@ -767,7 +755,7 @@ class SSLValidationHandler(urllib_request.BaseHandler):
ssl_s = ssl.wrap_socket(s, ca_certs=tmp_ca_cert_path, cert_reqs=ssl.CERT_REQUIRED, ssl_version=PROTOCOL)
match_hostname(ssl_s.getpeercert(), self.hostname)
# close the ssl connection
#ssl_s.unwrap()
# ssl_s.unwrap()
s.close()
except (ssl.SSLError, CertificateError):
e = get_exception()
@ -923,7 +911,7 @@ def open_url(url, data=None, headers=None, method=None, use_proxy=True,
data = to_bytes(data, nonstring='passthru')
if method:
if method.upper() not in ('OPTIONS','GET','HEAD','POST','PUT','DELETE','TRACE','CONNECT','PATCH'):
if method.upper() not in ('OPTIONS', 'GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'TRACE', 'CONNECT', 'PATCH'):
raise ConnectionError('invalid HTTP request method; %s' % method.upper())
request = RequestWithMethod(url, method.upper(), data)
else:
@ -951,7 +939,7 @@ def open_url(url, data=None, headers=None, method=None, use_proxy=True,
request.add_header(header, headers[header])
urlopen_args = [request, None]
if sys.version_info >= (2,6,0):
if sys.version_info >= (2, 6, 0):
# urlopen in python prior to 2.6.0 did not
# have a timeout parameter
urlopen_args.append(timeout)

@ -15,6 +15,7 @@
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
import os
try:
from pyvcloud.vcloudair import VCA
HAS_PYVCLOUD = True
@ -29,16 +30,18 @@ LOGIN_HOST = {'vca': 'vca.vmware.com', 'vchs': 'vchs.vmware.com'}
DEFAULT_SERVICE_TYPE = 'vca'
DEFAULT_VERSION = '5.7'
class VcaError(Exception):
def __init__(self, msg, **kwargs):
self.kwargs = kwargs
super(VcaError, self).__init__(msg)
def vca_argument_spec():
return dict(
username=dict(type='str', aliases=['user'], required=True),
password=dict(type='str', aliases=['pass','passwd'], required=True, no_log=True),
password=dict(type='str', aliases=['pass', 'passwd'], required=True, no_log=True),
org=dict(),
service_id=dict(),
instance_id=dict(),
@ -50,6 +53,7 @@ def vca_argument_spec():
verify_certs=dict(type='bool', default=True)
)
class VcaAnsibleModule(AnsibleModule):
def __init__(self, *args, **kwargs):
@ -193,7 +197,6 @@ class VcaAnsibleModule(AnsibleModule):
self.exit_json(**kwargs)
# -------------------------------------------------------------
# 9/18/2015 @privateip
# All of the functions below here were migrated from the original
@ -206,6 +209,7 @@ VCA_REQ_ARGS = ['instance_id', 'vdc_name']
VCHS_REQ_ARGS = ['service_id']
VCD_REQ_ARGS = []
def _validate_module(module):
if not HAS_PYVCLOUD:
module.fail_json(msg="python module pyvcloud is needed for this module")
@ -216,19 +220,19 @@ def _validate_module(module):
for arg in VCA_REQ_ARGS:
if module.params.get(arg) is None:
module.fail_json(msg="argument %s is mandatory when service type "
"is vca" % arg)
"is vca" % arg)
if service_type == 'vchs':
for arg in VCHS_REQ_ARGS:
if module.params.get(arg) is None:
module.fail_json(msg="argument %s is mandatory when service type "
"is vchs" % arg)
"is vchs" % arg)
if service_type == 'vcd':
for arg in VCD_REQ_ARGS:
if module.params.get(arg) is None:
module.fail_json(msg="argument %s is mandatory when service type "
"is vcd" % arg)
"is vcd" % arg)
def serialize_instances(instance_list):
@ -237,6 +241,7 @@ def serialize_instances(instance_list):
instances.append(dict(apiUrl=i['apiUrl'], instance_id=i['id']))
return instances
def _vca_login(vca, password, instance):
if not vca.login(password=password):
raise VcaError("Login Failed: Please check username or password",
@ -245,10 +250,11 @@ def _vca_login(vca, password, instance):
if not vca.login_to_instance_sso(instance=instance):
s_json = serialize_instances(vca.instances)
raise VcaError("Login to Instance failed: Seems like instance_id provided "
"is wrong .. Please check", valid_instances=s_json)
"is wrong .. Please check", valid_instances=s_json)
return vca
def _vchs_login(vca, password, service, org):
if not vca.login(password=password):
raise VcaError("Login Failed: Please check username or password",
@ -256,7 +262,7 @@ def _vchs_login(vca, password, service, org):
if not vca.login_to_org(service, org):
raise VcaError("Failed to login to org, Please check the orgname",
error=vca.response.content)
error=vca.response.content)
def _vcd_login(vca, password, org):
@ -272,6 +278,7 @@ def _vcd_login(vca, password, org):
if not vca.login(token=vca.token, org=org, org_url=vca.vcloud_session.org_url):
raise VcaError("Failed to login to org", error=vca.response.content)
def vca_login(module):
service_type = module.params.get('service_type')
username = module.params.get('username')
@ -323,8 +330,3 @@ def vca_login(module):
module.fail_json(msg=e.message, **e.kwargs)
return vca

@ -45,7 +45,7 @@ class Playbook:
# be either a play or an include statement
self._entries = []
self._basedir = to_text(os.getcwd(), errors='surrogate_or_strict')
self._loader = loader
self._loader = loader
self._file_name = None
@staticmethod

@ -21,6 +21,7 @@ __metaclass__ = type
from copy import deepcopy
class Attribute:
def __init__(self, isa=None, private=False, default=None, required=False, listof=None, priority=0, class_type=None, always_post_validate=False,

@ -149,21 +149,21 @@ class BaseMeta(type):
class Base(with_metaclass(BaseMeta, object)):
# connection/transport
_connection = FieldAttribute(isa='string')
_port = FieldAttribute(isa='int')
_remote_user = FieldAttribute(isa='string')
_connection = FieldAttribute(isa='string')
_port = FieldAttribute(isa='int')
_remote_user = FieldAttribute(isa='string')
# variables
_vars = FieldAttribute(isa='dict', priority=100, inherit=False)
_vars = FieldAttribute(isa='dict', priority=100, inherit=False)
# flags and misc. settings
_environment = FieldAttribute(isa='list')
_no_log = FieldAttribute(isa='bool')
_always_run = FieldAttribute(isa='bool')
_run_once = FieldAttribute(isa='bool')
_ignore_errors = FieldAttribute(isa='bool')
_check_mode = FieldAttribute(isa='bool')
_any_errors_fatal = FieldAttribute(isa='bool', default=False, always_post_validate=True)
_environment = FieldAttribute(isa='list')
_no_log = FieldAttribute(isa='bool')
_always_run = FieldAttribute(isa='bool')
_run_once = FieldAttribute(isa='bool')
_ignore_errors = FieldAttribute(isa='bool')
_check_mode = FieldAttribute(isa='bool')
_any_errors_fatal = FieldAttribute(isa='bool', default=False, always_post_validate=True)
# param names which have been deprecated/removed
DEPRECATED_ATTRIBUTES = [
@ -180,7 +180,7 @@ class Base(with_metaclass(BaseMeta, object)):
# other internal params
self._validated = False
self._squashed = False
self._squashed = False
self._finalized = False
# every object gets a random uuid:
@ -200,13 +200,13 @@ class Base(with_metaclass(BaseMeta, object)):
print("DUMPING OBJECT ------------------------------------------------------")
print("%s- %s (%s, id=%s)" % (" " * depth, self.__class__.__name__, self, id(self)))
if hasattr(self, '_parent') and self._parent:
self._parent.dump_me(depth+2)
self._parent.dump_me(depth + 2)
dep_chain = self._parent.get_dep_chain()
if dep_chain:
for dep in dep_chain:
dep.dump_me(depth+2)
dep.dump_me(depth + 2)
if hasattr(self, '_play') and self._play:
self._play.dump_me(depth+2)
self._play.dump_me(depth + 2)
def preprocess_data(self, ds):
''' infrequently used method to do some pre-processing of legacy terms '''
@ -405,12 +405,12 @@ class Base(with_metaclass(BaseMeta, object)):
)
value = value.split(',')
else:
value = [ value ]
value = [value]
if attribute.listof is not None:
for item in value:
if not isinstance(item, attribute.listof):
raise AnsibleParserError("the field '%s' should be a list of %s,"
" but the item '%s' is a %s" % (name, attribute.listof, item, type(item)), obj=self.get_ds())
raise AnsibleParserError("the field '%s' should be a list of %s, "
"but the item '%s' is a %s" % (name, attribute.listof, item, type(item)), obj=self.get_ds())
elif attribute.required and attribute.listof == string_types:
if item is None or item.strip() == "":
raise AnsibleParserError("the field '%s' is required, and cannot have empty values" % (name,), obj=self.get_ds())
@ -423,7 +423,7 @@ class Base(with_metaclass(BaseMeta, object)):
else:
# Making a list like this handles strings of
# text and bytes properly
value = [ value ]
value = [value]
if not isinstance(value, set):
value = set(value)
elif attribute.isa == 'dict':
@ -440,12 +440,12 @@ class Base(with_metaclass(BaseMeta, object)):
setattr(self, name, value)
except (TypeError, ValueError) as e:
raise AnsibleParserError("the field '%s' has an invalid value (%s), and could not be converted to an %s."
" Error was: %s" % (name, value, attribute.isa, e), obj=self.get_ds())
raise AnsibleParserError("the field '%s' has an invalid value (%s), and could not be converted to an %s. "
"The error was: %s" % (name, value, attribute.isa, e), obj=self.get_ds())
except (AnsibleUndefinedVariable, UndefinedError) as e:
if templar._fail_on_undefined_errors and name != 'name':
raise AnsibleParserError("the field '%s' has an invalid value, which appears to include a variable that is undefined."
" The error was: %s" % (name,e), obj=self.get_ds())
raise AnsibleParserError("the field '%s' has an invalid value, which appears to include a variable that is undefined. "
"The error was: %s" % (name, e), obj=self.get_ds())
self._finalized = True
@ -490,16 +490,16 @@ class Base(with_metaclass(BaseMeta, object)):
'''
if not isinstance(value, list):
value = [ value ]
value = [value]
if not isinstance(new_value, list):
new_value = [ new_value ]
new_value = [new_value]
if prepend:
combined = new_value + value
else:
combined = value + new_value
return [i for i,_ in itertools.groupby(combined) if i is not None]
return [i for i, _ in itertools.groupby(combined) if i is not None]
def dump_attrs(self):
'''

@ -29,13 +29,14 @@ except ImportError:
from ansible.utils.display import Display
display = Display()
class Become:
# Privilege escalation
_become = FieldAttribute(isa='bool')
_become_method = FieldAttribute(isa='string')
_become_user = FieldAttribute(isa='string')
_become_flags = FieldAttribute(isa='string')
_become = FieldAttribute(isa='bool')
_become_method = FieldAttribute(isa='string')
_become_user = FieldAttribute(isa='string')
_become_flags = FieldAttribute(isa='string')
def __init__(self):
super(Become, self).__init__()
@ -44,8 +45,8 @@ class Become:
# Fail out if user specifies conflicting privilege escalations
has_become = 'become' in ds or 'become_user'in ds
has_sudo = 'sudo' in ds or 'sudo_user' in ds
has_su = 'su' in ds or 'su_user' in ds
has_sudo = 'sudo' in ds or 'sudo_user' in ds
has_su = 'su' in ds or 'su_user' in ds
if has_become:
msg = 'The become params ("become", "become_user") and'
@ -101,4 +102,3 @@ class Become:
become_method = C.DEFAULT_BECOME_METHOD
if become_user is None:
become_user = C.DEFAULT_BECOME_USER

@ -28,29 +28,30 @@ from ansible.playbook.helpers import load_list_of_tasks
from ansible.playbook.role import Role
from ansible.playbook.taggable import Taggable
class Block(Base, Become, Conditional, Taggable):
# main block fields containing the task lists
_block = FieldAttribute(isa='list', default=[], inherit=False)
_rescue = FieldAttribute(isa='list', default=[], inherit=False)
_always = FieldAttribute(isa='list', default=[], inherit=False)
_block = FieldAttribute(isa='list', default=[], inherit=False)
_rescue = FieldAttribute(isa='list', default=[], inherit=False)
_always = FieldAttribute(isa='list', default=[], inherit=False)
# other fields
_delegate_to = FieldAttribute(isa='string')
_delegate_facts = FieldAttribute(isa='bool', default=False)
_name = FieldAttribute(isa='string', default='')
_delegate_to = FieldAttribute(isa='string')
_delegate_facts = FieldAttribute(isa='bool', default=False)
_name = FieldAttribute(isa='string', default='')
# for future consideration? this would be functionally
# similar to the 'else' clause for exceptions
#_otherwise = FieldAttribute(isa='list')
# _otherwise = FieldAttribute(isa='list')
def __init__(self, play=None, parent_block=None, role=None, task_include=None, use_handlers=False, implicit=False):
self._play = play
self._role = role
self._parent = None
self._dep_chain = None
self._play = play
self._role = role
self._parent = None
self._dep_chain = None
self._use_handlers = use_handlers
self._implicit = implicit
self._implicit = implicit
# end of role flag
self._eor = False
@ -182,9 +183,9 @@ class Block(Base, Become, Conditional, Taggable):
return new_task_list
new_me = super(Block, self).copy()
new_me._play = self._play
new_me._play = self._play
new_me._use_handlers = self._use_handlers
new_me._eor = self._eor
new_me._eor = self._eor
if self._dep_chain is not None:
new_me._dep_chain = self._dep_chain[:]
@ -194,7 +195,7 @@ class Block(Base, Become, Conditional, Taggable):
new_me._parent = self._parent.copy(exclude_tasks=exclude_tasks)
if not exclude_tasks:
new_me.block = _dupe_task_list(self.block or [], new_me)
new_me.block = _dupe_task_list(self.block or [], new_me)
new_me.rescue = _dupe_task_list(self.rescue or [], new_me)
new_me.always = _dupe_task_list(self.always or [], new_me)
@ -355,7 +356,7 @@ class Block(Base, Become, Conditional, Taggable):
def evaluate_block(block):
new_block = self.copy(exclude_tasks=True)
new_block.block = evaluate_and_append_task(block.block)
new_block.block = evaluate_and_append_task(block.block)
new_block.rescue = evaluate_and_append_task(block.rescue)
new_block.always = evaluate_and_append_task(block.always)
return new_block
@ -385,4 +386,3 @@ class Block(Base, Become, Conditional, Taggable):
return self._parent.all_parents_static()
return True

@ -41,6 +41,7 @@ DEFINED_REGEX = re.compile(r'(hostvars\[.+\]|[\w_]+)\s+(not\s+is|is|is\s+not)\s+
LOOKUP_REGEX = re.compile(r'lookup\s*\(')
VALID_VAR_REGEX = re.compile("^[_A-Za-z][_a-zA-Z0-9]*$")
class Conditional:
'''
@ -63,7 +64,7 @@ class Conditional:
def _validate_when(self, attr, name, value):
if not isinstance(value, list):
setattr(self, name, [ value ])
setattr(self, name, [value])
def _get_attr_when(self):
'''
@ -234,7 +235,4 @@ class Conditional:
# trigger the AnsibleUndefinedVariable exception again below
raise
except Exception as new_e:
raise AnsibleUndefinedVariable(
"error while evaluating conditional (%s): %s" % (original, e)
)
raise AnsibleUndefinedVariable("error while evaluating conditional (%s): %s" % (original, e))

@ -22,6 +22,7 @@ __metaclass__ = type
from ansible.playbook.attribute import FieldAttribute
from ansible.playbook.task import Task
class Handler(Task):
_listen = FieldAttribute(isa='list')
@ -41,7 +42,7 @@ class Handler(Task):
return t.load_data(data, variable_manager=variable_manager, loader=loader)
def flag_for_host(self, host):
#assert instanceof(host, Host)
# assert instanceof(host, Host)
if host not in self._flagged_hosts:
self._flagged_hosts.append(host)

@ -19,9 +19,10 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
#from ansible.inventory.host import Host
from ansible.playbook.task_include import TaskInclude
# from ansible.inventory.host import Host
from ansible.playbook.handler import Handler
from ansible.playbook.task_include import TaskInclude
class HandlerTaskInclude(Handler, TaskInclude):
@ -29,4 +30,3 @@ class HandlerTaskInclude(Handler, TaskInclude):
def load(data, block=None, role=None, task_include=None, variable_manager=None, loader=None):
t = HandlerTaskInclude(block=block, role=role, task_include=task_include)
return t.load_data(data, variable_manager=variable_manager, loader=loader)

@ -179,13 +179,13 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
include_target = templar.template(t.args['_raw_params'])
except AnsibleUndefinedVariable:
raise AnsibleParserError(
"Error when evaluating variable in include name: %s.\n\n" \
"When using static includes, ensure that any variables used in their names are defined in vars/vars_files\n" \
"or extra-vars passed in from the command line. Static includes cannot use variables from inventory\n" \
"Error when evaluating variable in include name: %s.\n\n"
"When using static includes, ensure that any variables used in their names are defined in vars/vars_files\n"
"or extra-vars passed in from the command line. Static includes cannot use variables from inventory\n"
"sources like group or host vars." % t.args['_raw_params'],
obj=task_ds,
suppress_extended_error=True,
)
)
if t._role:
include_file = loader.path_dwim_relative(t._role._role_path, subdir, include_target)
else:
@ -209,11 +209,11 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
C.DEFAULT_HANDLER_INCLUDES_STATIC and use_handlers:
raise
display.deprecated(
"Included file '%s' not found, however since this include is not " \
"explicitly marked as 'static: yes', we will try and include it dynamically " \
"later. In the future, this will be an error unless 'static: no' is used " \
"on the include task. If you do not want missing includes to be considered " \
"dynamic, use 'static: yes' on the include or set the global ansible.cfg " \
"Included file '%s' not found, however since this include is not "
"explicitly marked as 'static: yes', we will try and include it dynamically "
"later. In the future, this will be an error unless 'static: no' is used "
"on the include task. If you do not want missing includes to be considered "
"dynamic, use 'static: yes' on the include or set the global ansible.cfg "
"options to make all inclues static for tasks and/or handlers" % include_file, version="2.7"
)
task_list.append(t)
@ -242,7 +242,7 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
if len(tags) > 0:
if len(ti_copy.tags) > 0:
raise AnsibleParserError(
"Include tasks should not specify tags in more than one way (both via args and directly on the task). " \
"Include tasks should not specify tags in more than one way (both via args and directly on the task). "
"Mixing styles in which tags are specified is prohibited for whole import hierarchy, not only for single import statement",
obj=task_ds,
suppress_extended_error=True,
@ -275,8 +275,8 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
role=role,
task_include=None,
variable_manager=variable_manager,
loader=loader
)
loader=loader,
)
# 1. the user has set the 'static' option to false or true
# 2. one of the appropriate config options was set
@ -293,9 +293,11 @@ def load_list_of_tasks(ds, play, block=None, role=None, task_include=None, use_h
if not templar.is_template(ir.args[param]):
needs_templating = True
break
is_static = C.DEFAULT_TASK_INCLUDES_STATIC or \
(use_handlers and C.DEFAULT_HANDLER_INCLUDES_STATIC) or \
(not needs_templating and ir.all_parents_static() and not ir.loop)
is_static = (
C.DEFAULT_TASK_INCLUDES_STATIC or
(use_handlers and C.DEFAULT_HANDLER_INCLUDES_STATIC) or
(not needs_templating and ir.all_parents_static() and not ir.loop)
)
display.debug('Determined that if include_role static is %s' % str(is_static))
if is_static:
# uses compiled list from object
@ -331,4 +333,3 @@ def load_list_of_roles(ds, play, current_role_path=None, variable_manager=None,
roles.append(i)
return roles

@ -30,13 +30,14 @@ except ImportError:
from ansible.utils.display import Display
display = Display()
class IncludedFile:
def __init__(self, filename, args, task):
self._filename = filename
self._args = args
self._task = task
self._hosts = []
self._args = args
self._task = task
self._hosts = []
def add_host(self, host):
if host not in self._hosts:
@ -69,7 +70,7 @@ class IncludedFile:
continue
include_results = res._result['results']
else:
include_results = [ res._result ]
include_results = [res._result]
for include_result in include_results:
# if the task result was skipped or failed, continue

@ -26,8 +26,8 @@ from ansible.playbook.base import Base
class LoopControl(Base):
_loop_var = FieldAttribute(isa='str')
_label = FieldAttribute(isa='str')
_pause = FieldAttribute(isa='int')
_label = FieldAttribute(isa='str')
_pause = FieldAttribute(isa='int')
def __init__(self):
super(LoopControl, self).__init__()
@ -36,4 +36,3 @@ class LoopControl(Base):
def load(data, variable_manager=None, loader=None):
t = LoopControl()
return t.load_data(data, variable_manager=variable_manager, loader=loader)

@ -20,10 +20,8 @@ from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from ansible import constants as C
from ansible.errors import AnsibleParserError
from ansible.module_utils.six import string_types
from ansible.playbook.attribute import FieldAttribute
from ansible.playbook.base import Base
from ansible.playbook.become import Become
@ -56,40 +54,40 @@ class Play(Base, Taggable, Become):
"""
# =================================================================================
_name = FieldAttribute(isa='string', default='', always_post_validate=True)
_name = FieldAttribute(isa='string', default='', always_post_validate=True)
# TODO: generalize connection
_accelerate = FieldAttribute(isa='bool', default=False, always_post_validate=True)
_accelerate_ipv6 = FieldAttribute(isa='bool', default=False, always_post_validate=True)
_accelerate_port = FieldAttribute(isa='int', default=5099, always_post_validate=True)
_accelerate = FieldAttribute(isa='bool', default=False, always_post_validate=True)
_accelerate_ipv6 = FieldAttribute(isa='bool', default=False, always_post_validate=True)
_accelerate_port = FieldAttribute(isa='int', default=5099, always_post_validate=True)
# Connection
_fact_path = FieldAttribute(isa='string', default=None)
_gather_facts = FieldAttribute(isa='bool', default=None, always_post_validate=True)
_gather_subset = FieldAttribute(isa='barelist', default=None, always_post_validate=True)
_gather_timeout = FieldAttribute(isa='int', default=None, always_post_validate=True)
_hosts = FieldAttribute(isa='list', required=True, listof=string_types, always_post_validate=True)
_fact_path = FieldAttribute(isa='string', default=None)
_gather_facts = FieldAttribute(isa='bool', default=None, always_post_validate=True)
_gather_subset = FieldAttribute(isa='barelist', default=None, always_post_validate=True)
_gather_timeout = FieldAttribute(isa='int', default=None, always_post_validate=True)
_hosts = FieldAttribute(isa='list', required=True, listof=string_types, always_post_validate=True)
# Variable Attributes
_vars_files = FieldAttribute(isa='list', default=[], priority=99)
_vars_prompt = FieldAttribute(isa='list', default=[], always_post_validate=True)
_vault_password = FieldAttribute(isa='string', always_post_validate=True)
_vars_files = FieldAttribute(isa='list', default=[], priority=99)
_vars_prompt = FieldAttribute(isa='list', default=[], always_post_validate=True)
_vault_password = FieldAttribute(isa='string', always_post_validate=True)
# Role Attributes
_roles = FieldAttribute(isa='list', default=[], priority=90)
_roles = FieldAttribute(isa='list', default=[], priority=90)
# Block (Task) Lists Attributes
_handlers = FieldAttribute(isa='list', default=[])
_pre_tasks = FieldAttribute(isa='list', default=[])
_post_tasks = FieldAttribute(isa='list', default=[])
_tasks = FieldAttribute(isa='list', default=[])
_handlers = FieldAttribute(isa='list', default=[])
_pre_tasks = FieldAttribute(isa='list', default=[])
_post_tasks = FieldAttribute(isa='list', default=[])
_tasks = FieldAttribute(isa='list', default=[])
# Flag/Setting Attributes
_force_handlers = FieldAttribute(isa='bool', always_post_validate=True)
_force_handlers = FieldAttribute(isa='bool', always_post_validate=True)
_max_fail_percentage = FieldAttribute(isa='percent', always_post_validate=True)
_serial = FieldAttribute(isa='list', default=[], always_post_validate=True)
_strategy = FieldAttribute(isa='string', default=C.DEFAULT_STRATEGY, always_post_validate=True)
_order = FieldAttribute(isa='string', always_post_validate=True)
_serial = FieldAttribute(isa='list', default=[], always_post_validate=True)
_strategy = FieldAttribute(isa='string', default=C.DEFAULT_STRATEGY, always_post_validate=True)
_order = FieldAttribute(isa='string', always_post_validate=True)
# =================================================================================
@ -132,8 +130,8 @@ class Play(Base, Taggable, Become):
# this should never happen, but error out with a helpful message
# to the user if it does...
if 'remote_user' in ds:
raise AnsibleParserError("both 'user' and 'remote_user' are set for %s."
" The use of 'user' is deprecated, and should be removed" % self.get_name(), obj=ds)
raise AnsibleParserError("both 'user' and 'remote_user' are set for %s. "
"The use of 'user' is deprecated, and should be removed" % self.get_name(), obj=ds)
ds['remote_user'] = ds['user']
del ds['user']
@ -207,14 +205,14 @@ class Play(Base, Taggable, Become):
display.deprecated("Using the 'short form' for vars_prompt has been deprecated", version="2.7")
for vname, prompt in prompt_data.items():
vars_prompts.append(dict(
name = vname,
prompt = prompt,
default = None,
private = None,
confirm = None,
encrypt = None,
salt_size = None,
salt = None,
name=vname,
prompt=prompt,
default=None,
private=None,
confirm=None,
encrypt=None,
salt_size=None,
salt=None,
))
else:
vars_prompts.append(prompt_data)

@ -54,42 +54,42 @@ except ImportError:
# in variable names.
MAGIC_VARIABLE_MAPPING = dict(
connection = ('ansible_connection',),
remote_addr = ('ansible_ssh_host', 'ansible_host'),
remote_user = ('ansible_ssh_user', 'ansible_user'),
port = ('ansible_ssh_port', 'ansible_port'),
timeout = ('ansible_ssh_timeout', 'ansible_timeout'),
ssh_executable = ('ansible_ssh_executable',),
accelerate_port = ('ansible_accelerate_port',),
password = ('ansible_ssh_pass', 'ansible_password'),
private_key_file = ('ansible_ssh_private_key_file', 'ansible_private_key_file'),
pipelining = ('ansible_ssh_pipelining', 'ansible_pipelining'),
shell = ('ansible_shell_type',),
network_os = ('ansible_network_os',),
become = ('ansible_become',),
become_method = ('ansible_become_method',),
become_user = ('ansible_become_user',),
become_pass = ('ansible_become_password','ansible_become_pass'),
become_exe = ('ansible_become_exe',),
become_flags = ('ansible_become_flags',),
ssh_common_args = ('ansible_ssh_common_args',),
docker_extra_args= ('ansible_docker_extra_args',),
sftp_extra_args = ('ansible_sftp_extra_args',),
scp_extra_args = ('ansible_scp_extra_args',),
ssh_extra_args = ('ansible_ssh_extra_args',),
ssh_transfer_method = ('ansible_ssh_transfer_method',),
sudo = ('ansible_sudo',),
sudo_user = ('ansible_sudo_user',),
sudo_pass = ('ansible_sudo_password', 'ansible_sudo_pass'),
sudo_exe = ('ansible_sudo_exe',),
sudo_flags = ('ansible_sudo_flags',),
su = ('ansible_su',),
su_user = ('ansible_su_user',),
su_pass = ('ansible_su_password', 'ansible_su_pass'),
su_exe = ('ansible_su_exe',),
su_flags = ('ansible_su_flags',),
executable = ('ansible_shell_executable',),
module_compression = ('ansible_module_compression',),
connection=('ansible_connection', ),
remote_addr=('ansible_ssh_host', 'ansible_host'),
remote_user=('ansible_ssh_user', 'ansible_user'),
port=('ansible_ssh_port', 'ansible_port'),
timeout=('ansible_ssh_timeout', 'ansible_timeout'),
ssh_executable=('ansible_ssh_executable', ),
accelerate_port=('ansible_accelerate_port', ),
password=('ansible_ssh_pass', 'ansible_password'),
private_key_file=('ansible_ssh_private_key_file', 'ansible_private_key_file'),
pipelining=('ansible_ssh_pipelining', 'ansible_pipelining'),
shell=('ansible_shell_type', ),
network_os=('ansible_network_os', ),
become=('ansible_become', ),
become_method=('ansible_become_method', ),
become_user=('ansible_become_user', ),
become_pass=('ansible_become_password', 'ansible_become_pass'),
become_exe=('ansible_become_exe', ),
become_flags=('ansible_become_flags', ),
ssh_common_args=('ansible_ssh_common_args', ),
docker_extra_args=('ansible_docker_extra_args', ),
sftp_extra_args=('ansible_sftp_extra_args', ),
scp_extra_args=('ansible_scp_extra_args', ),
ssh_extra_args=('ansible_ssh_extra_args', ),
ssh_transfer_method=('ansible_ssh_transfer_method', ),
sudo=('ansible_sudo', ),
sudo_user=('ansible_sudo_user', ),
sudo_pass=('ansible_sudo_password', 'ansible_sudo_pass'),
sudo_exe=('ansible_sudo_exe', ),
sudo_flags=('ansible_sudo_flags', ),
su=('ansible_su', ),
su_user=('ansible_su_user', ),
su_pass=('ansible_su_password', 'ansible_su_pass'),
su_exe=('ansible_su_exe', ),
su_flags=('ansible_su_flags', ),
executable=('ansible_shell_executable', ),
module_compression=('ansible_module_compression', ),
)
b_SU_PROMPT_LOCALIZATIONS = [
@ -155,6 +155,7 @@ RESET_VARS = (
'ansible_port',
)
class PlayContext(Base):
'''
@ -165,60 +166,60 @@ class PlayContext(Base):
# connection fields, some are inherited from Base:
# (connection, port, remote_user, environment, no_log)
_docker_extra_args = FieldAttribute(isa='string')
_remote_addr = FieldAttribute(isa='string')
_password = FieldAttribute(isa='string')
_docker_extra_args = FieldAttribute(isa='string')
_remote_addr = FieldAttribute(isa='string')
_password = FieldAttribute(isa='string')
_private_key_file = FieldAttribute(isa='string', default=C.DEFAULT_PRIVATE_KEY_FILE)
_timeout = FieldAttribute(isa='int', default=C.DEFAULT_TIMEOUT)
_shell = FieldAttribute(isa='string')
_network_os = FieldAttribute(isa='string')
_connection_user = FieldAttribute(isa='string')
_ssh_args = FieldAttribute(isa='string', default=C.ANSIBLE_SSH_ARGS)
_ssh_common_args = FieldAttribute(isa='string')
_sftp_extra_args = FieldAttribute(isa='string')
_scp_extra_args = FieldAttribute(isa='string')
_ssh_extra_args = FieldAttribute(isa='string')
_ssh_executable = FieldAttribute(isa='string', default=C.ANSIBLE_SSH_EXECUTABLE)
_timeout = FieldAttribute(isa='int', default=C.DEFAULT_TIMEOUT)
_shell = FieldAttribute(isa='string')
_network_os = FieldAttribute(isa='string')
_connection_user = FieldAttribute(isa='string')
_ssh_args = FieldAttribute(isa='string', default=C.ANSIBLE_SSH_ARGS)
_ssh_common_args = FieldAttribute(isa='string')
_sftp_extra_args = FieldAttribute(isa='string')
_scp_extra_args = FieldAttribute(isa='string')
_ssh_extra_args = FieldAttribute(isa='string')
_ssh_executable = FieldAttribute(isa='string', default=C.ANSIBLE_SSH_EXECUTABLE)
_ssh_transfer_method = FieldAttribute(isa='string', default=C.DEFAULT_SSH_TRANSFER_METHOD)
_connection_lockfd= FieldAttribute(isa='int')
_pipelining = FieldAttribute(isa='bool', default=C.ANSIBLE_SSH_PIPELINING)
_accelerate = FieldAttribute(isa='bool', default=False)
_accelerate_ipv6 = FieldAttribute(isa='bool', default=False, always_post_validate=True)
_accelerate_port = FieldAttribute(isa='int', default=C.ACCELERATE_PORT, always_post_validate=True)
_executable = FieldAttribute(isa='string', default=C.DEFAULT_EXECUTABLE)
_connection_lockfd = FieldAttribute(isa='int')
_pipelining = FieldAttribute(isa='bool', default=C.ANSIBLE_SSH_PIPELINING)
_accelerate = FieldAttribute(isa='bool', default=False)
_accelerate_ipv6 = FieldAttribute(isa='bool', default=False, always_post_validate=True)
_accelerate_port = FieldAttribute(isa='int', default=C.ACCELERATE_PORT, always_post_validate=True)
_executable = FieldAttribute(isa='string', default=C.DEFAULT_EXECUTABLE)
_module_compression = FieldAttribute(isa='string', default=C.DEFAULT_MODULE_COMPRESSION)
# privilege escalation fields
_become = FieldAttribute(isa='bool')
_become_method = FieldAttribute(isa='string')
_become_user = FieldAttribute(isa='string')
_become_pass = FieldAttribute(isa='string')
_become_exe = FieldAttribute(isa='string')
_become_flags = FieldAttribute(isa='string')
_prompt = FieldAttribute(isa='string')
_become = FieldAttribute(isa='bool')
_become_method = FieldAttribute(isa='string')
_become_user = FieldAttribute(isa='string')
_become_pass = FieldAttribute(isa='string')
_become_exe = FieldAttribute(isa='string')
_become_flags = FieldAttribute(isa='string')
_prompt = FieldAttribute(isa='string')
# backwards compatibility fields for sudo/su
_sudo_exe = FieldAttribute(isa='string')
_sudo_flags = FieldAttribute(isa='string')
_sudo_pass = FieldAttribute(isa='string')
_su_exe = FieldAttribute(isa='string')
_su_flags = FieldAttribute(isa='string')
_su_pass = FieldAttribute(isa='string')
_sudo_exe = FieldAttribute(isa='string')
_sudo_flags = FieldAttribute(isa='string')
_sudo_pass = FieldAttribute(isa='string')
_su_exe = FieldAttribute(isa='string')
_su_flags = FieldAttribute(isa='string')
_su_pass = FieldAttribute(isa='string')
# general flags
_verbosity = FieldAttribute(isa='int', default=0)
_only_tags = FieldAttribute(isa='set', default=set())
_skip_tags = FieldAttribute(isa='set', default=set())
_check_mode = FieldAttribute(isa='bool', default=False)
_force_handlers = FieldAttribute(isa='bool', default=False)
_start_at_task = FieldAttribute(isa='string')
_step = FieldAttribute(isa='bool', default=False)
_diff = FieldAttribute(isa='bool', default=C.DIFF_ALWAYS)
_verbosity = FieldAttribute(isa='int', default=0)
_only_tags = FieldAttribute(isa='set', default=set())
_skip_tags = FieldAttribute(isa='set', default=set())
_check_mode = FieldAttribute(isa='bool', default=False)
_force_handlers = FieldAttribute(isa='bool', default=False)
_start_at_task = FieldAttribute(isa='string')
_step = FieldAttribute(isa='bool', default=False)
_diff = FieldAttribute(isa='bool', default=C.DIFF_ALWAYS)
# Fact gathering settings
_gather_subset = FieldAttribute(isa='string', default=C.DEFAULT_GATHER_SUBSET)
_gather_timeout = FieldAttribute(isa='string', default=C.DEFAULT_GATHER_TIMEOUT)
_fact_path = FieldAttribute(isa='string', default=C.DEFAULT_FACT_PATH)
_gather_subset = FieldAttribute(isa='string', default=C.DEFAULT_GATHER_SUBSET)
_gather_timeout = FieldAttribute(isa='string', default=C.DEFAULT_GATHER_TIMEOUT)
_fact_path = FieldAttribute(isa='string', default=C.DEFAULT_FACT_PATH)
def __init__(self, play=None, options=None, passwords=None, connection_lockfd=None):
@ -227,10 +228,10 @@ class PlayContext(Base):
if passwords is None:
passwords = {}
self.password = passwords.get('conn_pass','')
self.become_pass = passwords.get('become_pass','')
self.password = passwords.get('conn_pass', '')
self.become_pass = passwords.get('become_pass', '')
self.prompt = ''
self.prompt = ''
self.success_key = ''
# a file descriptor to be used during locking operations
@ -243,7 +244,6 @@ class PlayContext(Base):
if play:
self.set_play(play)
def set_play(self, play):
'''
Configures this connection information instance with data from
@ -283,18 +283,18 @@ class PlayContext(Base):
'''
# privilege escalation
self.become = options.become
self.become = options.become
self.become_method = options.become_method
self.become_user = options.become_user
self.become_user = options.become_user
self.check_mode = boolean(options.check)
# get ssh options FIXME: make these common to all connections
for flag in ['ssh_common_args', 'docker_extra_args', 'sftp_extra_args', 'scp_extra_args', 'ssh_extra_args']:
setattr(self, flag, getattr(options,flag, ''))
setattr(self, flag, getattr(options, flag, ''))
# general flags (should we move out?)
for flag in ['connection','remote_user', 'private_key_file', 'verbosity', 'force_handlers', 'step', 'start_at_task', 'diff']:
for flag in ['connection', 'remote_user', 'private_key_file', 'verbosity', 'force_handlers', 'step', 'start_at_task', 'diff']:
attribute = getattr(options, flag, False)
if attribute:
setattr(self, flag, attribute)
@ -435,7 +435,7 @@ class PlayContext(Base):
if connection_type in delegated_vars:
break
else:
remote_addr_local = new_info.remote_addr in C.LOCALHOST
remote_addr_local = new_info.remote_addr in C.LOCALHOST
inv_hostname_local = delegated_vars.get('inventory_hostname') in C.LOCALHOST
if remote_addr_local and inv_hostname_local:
setattr(new_info, 'connection', 'local')
@ -464,13 +464,12 @@ class PlayContext(Base):
if task.check_mode is not None:
new_info.check_mode = task.check_mode
return new_info
def make_become_cmd(self, cmd, executable=None):
""" helper function to create privilege escalation commands """
prompt = None
prompt = None
success_key = None
self.prompt = None
@ -479,8 +478,8 @@ class PlayContext(Base):
if not executable:
executable = self.executable
becomecmd = None
randbits = ''.join(random.choice(string.ascii_lowercase) for x in range(32))
becomecmd = None
randbits = ''.join(random.choice(string.ascii_lowercase) for x in range(32))
success_key = 'BECOME-SUCCESS-%s' % randbits
success_cmd = shlex_quote('echo %s; %s' % (success_key, cmd))
@ -490,18 +489,22 @@ class PlayContext(Base):
command = success_cmd
# set executable to use for the privilege escalation method, with various overrides
exe = self.become_exe or \
getattr(self, '%s_exe' % self.become_method, None) or \
C.DEFAULT_BECOME_EXE or \
getattr(C, 'DEFAULT_%s_EXE' % self.become_method.upper(), None) or \
self.become_method
exe = (
self.become_exe or
getattr(self, '%s_exe' % self.become_method, None) or
C.DEFAULT_BECOME_EXE or
getattr(C, 'DEFAULT_%s_EXE' % self.become_method.upper(), None) or
self.become_method
)
# set flags to use for the privilege escalation method, with various overrides
flags = self.become_flags or \
getattr(self, '%s_flags' % self.become_method, None) or \
C.DEFAULT_BECOME_FLAGS or \
getattr(C, 'DEFAULT_%s_FLAGS' % self.become_method.upper(), None) or \
''
flags = (
self.become_flags or
getattr(self, '%s_flags' % self.become_method, None) or
C.DEFAULT_BECOME_FLAGS or
getattr(C, 'DEFAULT_%s_FLAGS' % self.become_method.upper(), None) or
''
)
if self.become_method == 'sudo':
# If we have a password, we run sudo with a randomly-generated
@ -517,11 +520,10 @@ class PlayContext(Base):
# force quick error if password is required but not supplied, should prevent sudo hangs.
if self.become_pass:
prompt = '[sudo via ansible, key=%s] password: ' % randbits
becomecmd = '%s %s -p "%s" -u %s %s' % (exe, flags.replace('-n',''), prompt, self.become_user, command)
becomecmd = '%s %s -p "%s" -u %s %s' % (exe, flags.replace('-n', ''), prompt, self.become_user, command)
else:
becomecmd = '%s %s -u %s %s' % (exe, flags, self.become_user, command)
elif self.become_method == 'su':
# passing code ref to examine prompt as simple string comparisson isn't good enough with su
@ -537,7 +539,7 @@ class PlayContext(Base):
elif self.become_method == 'pbrun':
prompt='Password:'
prompt = 'Password:'
becomecmd = '%s %s -u %s %s' % (exe, flags, self.become_user, success_cmd)
elif self.become_method == 'ksu':
@ -575,7 +577,7 @@ class PlayContext(Base):
if self.become_user:
flags += ' -u %s ' % self.become_user
#FIXME: make shell independent
# FIXME: make shell independent
becomecmd = '%s %s echo %s && %s %s env ANSIBLE=true %s' % (exe, flags, success_key, exe, flags, cmd)
elif self.become_method == 'dzdo':
@ -591,7 +593,7 @@ class PlayContext(Base):
exe = self.become_exe or 'pmrun'
prompt='Enter UPM user password:'
prompt = 'Enter UPM user password:'
becomecmd = '%s %s %s' % (exe, flags, shlex_quote(command))
else:
@ -645,4 +647,3 @@ class PlayContext(Base):
self.connection = conn_type
return self._attributes['connection']

@ -34,9 +34,9 @@ from ansible.template import Templar
class PlaybookInclude(Base, Conditional, Taggable):
_name = FieldAttribute(isa='string')
_include = FieldAttribute(isa='string')
_vars = FieldAttribute(isa='dict', default=dict())
_name = FieldAttribute(isa='string')
_include = FieldAttribute(isa='string')
_vars = FieldAttribute(isa='dict', default=dict())
@staticmethod
def load(data, basedir, variable_manager=None, loader=None):
@ -113,7 +113,7 @@ class PlaybookInclude(Base, Conditional, Taggable):
if isinstance(ds, AnsibleBaseYAMLObject):
new_ds.ansible_pos = ds.ansible_pos
for (k,v) in iteritems(ds):
for (k, v) in iteritems(ds):
if k == 'include':
self._preprocess_include(ds, new_ds, k, v)
else:
@ -152,4 +152,3 @@ class PlaybookInclude(Base, Conditional, Taggable):
if 'vars' in new_ds:
raise AnsibleParserError("include parameters cannot be mixed with 'vars' entries for include statements", obj=ds)
new_ds['vars'] = params

@ -42,6 +42,7 @@ __all__ = ['Role', 'hash_params']
# in a static method. This is also used in the base class for
# strategies (ansible/plugins/strategy/__init__.py)
def hash_params(params):
"""
Construct a data structure of parameters that is hashable.
@ -96,21 +97,21 @@ class Role(Base, Become, Conditional, Taggable):
_delegate_facts = FieldAttribute(isa='bool', default=False)
def __init__(self, play=None, from_files=None):
self._role_name = None
self._role_path = None
self._role_params = dict()
self._loader = None
self._metadata = None
self._play = play
self._parents = []
self._dependencies = []
self._task_blocks = []
self._handler_blocks = []
self._default_vars = dict()
self._role_vars = dict()
self._had_task_run = dict()
self._completed = dict()
self._role_name = None
self._role_path = None
self._role_params = dict()
self._loader = None
self._metadata = None
self._play = play
self._parents = []
self._dependencies = []
self._task_blocks = []
self._handler_blocks = []
self._default_vars = dict()
self._role_vars = dict()
self._had_task_run = dict()
self._completed = dict()
if from_files is None:
from_files = {}
@ -166,11 +167,11 @@ class Role(Base, Become, Conditional, Taggable):
obj=role_include._ds)
def _load_role_data(self, role_include, parent_role=None):
self._role_name = role_include.role
self._role_path = role_include.get_role_path()
self._role_params = role_include.get_role_params()
self._role_name = role_include.role
self._role_path = role_include.get_role_path()
self._role_params = role_include.get_role_params()
self._variable_manager = role_include.get_variable_manager()
self._loader = role_include.get_loader()
self._loader = role_include.get_loader()
if parent_role:
self.add_parent(parent_role)
@ -209,7 +210,7 @@ class Role(Base, Become, Conditional, Taggable):
try:
self._task_blocks = load_list_of_blocks(task_data, play=self._play, role=self, loader=self._loader, variable_manager=self._variable_manager)
except AssertionError:
raise AnsibleParserError("The tasks/main.yml file for role '%s' must contain a list of tasks" % self._role_name , obj=task_data)
raise AnsibleParserError("The tasks/main.yml file for role '%s' must contain a list of tasks" % self._role_name, obj=task_data)
handler_data = self._load_role_yaml('handlers')
if handler_data:
@ -217,10 +218,10 @@ class Role(Base, Become, Conditional, Taggable):
self._handler_blocks = load_list_of_blocks(handler_data, play=self._play, role=self, use_handlers=True, loader=self._loader,
variable_manager=self._variable_manager)
except AssertionError:
raise AnsibleParserError("The handlers/main.yml file for role '%s' must contain a list of tasks" % self._role_name , obj=handler_data)
raise AnsibleParserError("The handlers/main.yml file for role '%s' must contain a list of tasks" % self._role_name, obj=handler_data)
# vars and default vars are regular dictionaries
self._role_vars = self._load_role_yaml('vars', main=self._from_files.get('vars'))
self._role_vars = self._load_role_yaml('vars', main=self._from_files.get('vars'))
if self._role_vars is None:
self._role_vars = dict()
elif not isinstance(self._role_vars, dict):
@ -239,7 +240,7 @@ class Role(Base, Become, Conditional, Taggable):
if self._loader.path_exists(main_file):
return self._loader.load_from_file(main_file)
elif main is not None:
raise AnsibleParserError("Could not find specified file in role: %s/%s" % (subdir,main))
raise AnsibleParserError("Could not find specified file in role: %s/%s" % (subdir, main))
return None
def _resolve_main(self, basepath, main=None):
@ -269,8 +270,8 @@ class Role(Base, Become, Conditional, Taggable):
else:
for m in possible_mains:
if self._loader.is_file(m):
return m # exactly one main file
return possible_mains[0] # zero mains (we still need to return something)
return m # exactly one main file
return possible_mains[0] # zero mains (we still need to return something)
def _load_dependencies(self):
'''
@ -286,7 +287,6 @@ class Role(Base, Become, Conditional, Taggable):
return deps
#------------------------------------------------------------------------------
# other functions
def add_parent(self, parent_role):
@ -347,7 +347,7 @@ class Role(Base, Become, Conditional, Taggable):
in the proper order in which they should be executed or evaluated.
'''
child_deps = []
child_deps = []
for dep in self.get_direct_dependencies():
for child_dep in dep.get_all_dependencies():
@ -425,13 +425,13 @@ class Role(Base, Become, Conditional, Taggable):
def serialize(self, include_deps=True):
res = super(Role, self).serialize()
res['_role_name'] = self._role_name
res['_role_path'] = self._role_path
res['_role_vars'] = self._role_vars
res['_role_params'] = self._role_params
res['_role_name'] = self._role_name
res['_role_path'] = self._role_path
res['_role_vars'] = self._role_vars
res['_role_params'] = self._role_params
res['_default_vars'] = self._default_vars
res['_had_task_run'] = self._had_task_run.copy()
res['_completed'] = self._completed.copy()
res['_completed'] = self._completed.copy()
if self._metadata:
res['_metadata'] = self._metadata.serialize()
@ -450,13 +450,13 @@ class Role(Base, Become, Conditional, Taggable):
return res
def deserialize(self, data, include_deps=True):
self._role_name = data.get('_role_name', '')
self._role_path = data.get('_role_path', '')
self._role_vars = data.get('_role_vars', dict())
self._role_params = data.get('_role_params', dict())
self._role_name = data.get('_role_name', '')
self._role_path = data.get('_role_path', '')
self._role_vars = data.get('_role_vars', dict())
self._role_params = data.get('_role_params', dict())
self._default_vars = data.get('_default_vars', dict())
self._had_task_run = data.get('_had_task_run', dict())
self._completed = data.get('_completed', dict())
self._completed = data.get('_completed', dict())
if include_deps:
deps = []
@ -488,4 +488,3 @@ class Role(Base, Become, Conditional, Taggable):
parent.set_loader(loader)
for dep in self.get_direct_dependencies():
dep.set_loader(loader)

@ -51,16 +51,16 @@ class RoleDefinition(Base, Become, Conditional, Taggable):
super(RoleDefinition, self).__init__()
self._play = play
self._play = play
self._variable_manager = variable_manager
self._loader = loader
self._loader = loader
self._role_path = None
self._role_path = None
self._role_basedir = role_basedir
self._role_params = dict()
self._role_params = dict()
#def __repr__(self):
# return 'ROLEDEF: ' + self._attributes.get('role', '<no name set>')
# def __repr__(self):
# return 'ROLEDEF: ' + self._attributes.get('role', '<no name set>')
@staticmethod
def load(data, variable_manager=None, loader=None):
@ -205,8 +205,8 @@ class RoleDefinition(Base, Become, Conditional, Taggable):
# remember to update it manually.
if key not in base_attribute_names or key in ('connection', 'port', 'remote_user'):
if key in ('connection', 'port', 'remote_user'):
display.deprecated("Using '%s' as a role param has been deprecated. " % key + \
"In the future, these values should be entered in the `vars:` " + \
display.deprecated("Using '%s' as a role param has been deprecated. " % key +
"In the future, these values should be entered in the `vars:` " +
"section for roles, but for now we'll store it as both a param and an attribute.", version="2.7")
role_def[key] = value
# this key does not match a field attribute, so it must be a role param

@ -40,7 +40,7 @@ class RoleInclude(RoleDefinition):
is included for execution in a play.
"""
_delegate_to = FieldAttribute(isa='string')
_delegate_to = FieldAttribute(isa='string')
_delegate_facts = FieldAttribute(isa='bool', default=False)
def __init__(self, play=None, role_basedir=None, variable_manager=None, loader=None):
@ -57,4 +57,3 @@ class RoleInclude(RoleDefinition):
ri = RoleInclude(play=play, role_basedir=current_role_path, variable_manager=variable_manager, loader=loader)
return ri.load_data(data, variable_manager=variable_manager, loader=loader)

@ -39,8 +39,8 @@ class RoleMetadata(Base):
'''
_allow_duplicates = FieldAttribute(isa='bool', default=False)
_dependencies = FieldAttribute(isa='list', default=[])
_galaxy_info = FieldAttribute(isa='GalaxyInfo')
_dependencies = FieldAttribute(isa='list', default=[])
_galaxy_info = FieldAttribute(isa='GalaxyInfo')
def __init__(self, owner=None):
self._owner = owner
@ -103,8 +103,8 @@ class RoleMetadata(Base):
def serialize(self):
return dict(
allow_duplicates = self._allow_duplicates,
dependencies = self._dependencies,
allow_duplicates=self._allow_duplicates,
dependencies=self._dependencies,
)
def deserialize(self, data):

@ -46,6 +46,7 @@ except ImportError:
from ansible.utils.display import Display
display = Display()
class RoleRequirement(RoleDefinition):
"""
@ -193,7 +194,7 @@ class RoleRequirement(RoleDefinition):
raise AnsibleError("error executing: %s" % " ".join(clone_cmd))
rc = popen.wait()
if rc != 0:
raise AnsibleError ("- command %s failed in directory %s (rc=%s)" % (' '.join(clone_cmd), tempdir, rc))
raise AnsibleError("- command %s failed in directory %s (rc=%s)" % (' '.join(clone_cmd), tempdir, rc))
if scm == 'git' and version:
checkout_cmd = [scm, 'checkout', version]
@ -228,4 +229,3 @@ class RoleRequirement(RoleDefinition):
shutil.rmtree(tempdir, ignore_errors=True)
return temp_file.name

@ -60,12 +60,11 @@ class IncludeRole(Task):
self._parent_role = role
self._role_name = None
def get_block_list(self, play=None, variable_manager=None, loader=None):
# only need play passed in when dynamic
if play is None:
myplay = self._parent._play
myplay = self._parent._play
else:
myplay = play
@ -99,7 +98,7 @@ class IncludeRole(Task):
ir = IncludeRole(block, role, task_include=task_include).load_data(data, variable_manager=variable_manager, loader=loader)
### Process options
# Process options
# name is needed, or use role as alias
ir._role_name = ir.args.get('name', ir.args.get('role'))
if ir._role_name is None:
@ -107,11 +106,11 @@ class IncludeRole(Task):
# build options for role includes
for key in ['tasks', 'vars', 'defaults']:
from_key ='%s_from' % key
from_key = '%s_from' % key
if ir.args.get(from_key):
ir._from_files[key] = basename(ir.args.get(from_key))
#FIXME: find a way to make this list come from object ( attributes does not work as per below)
# FIXME: find a way to make this list come from object ( attributes does not work as per below)
# manual list as otherwise the options would set other task parameters we don't want.
for option in ['private', 'allow_duplicates']:
if option in ir.args:
@ -125,7 +124,7 @@ class IncludeRole(Task):
new_me.statically_loaded = self.statically_loaded
new_me._from_files = self._from_files.copy()
new_me._parent_role = self._parent_role
new_me._role_name = self._role_name
new_me._role_name = self._role_name
return new_me

@ -30,7 +30,7 @@ from ansible.template import Templar
class Taggable:
untagged = frozenset(['untagged'])
_tags = FieldAttribute(isa='list', default=[], listof=(string_types,int))
_tags = FieldAttribute(isa='list', default=[], listof=(string_types, int))
def __init__(self):
super(Taggable, self).__init__()
@ -41,9 +41,9 @@ class Taggable:
elif isinstance(ds, string_types):
value = ds.split(',')
if isinstance(value, list):
return [ x.strip() for x in value ]
return [x.strip() for x in value]
else:
return [ ds ]
return [ds]
else:
raise AnsibleError('tags must be specified as a list', obj=ds)
@ -73,7 +73,7 @@ class Taggable:
else:
tags = set([tags])
else:
tags = set([i for i,_ in itertools.groupby(tags)])
tags = set([i for i, _ in itertools.groupby(tags)])
else:
# this makes isdisjoint work for untagged
tags = self.untagged

@ -65,29 +65,29 @@ class Task(Base, Conditional, Taggable, Become):
# will be used if defined
# might be possible to define others
_args = FieldAttribute(isa='dict', default=dict())
_action = FieldAttribute(isa='string')
_async = FieldAttribute(isa='int', default=0)
_changed_when = FieldAttribute(isa='list', default=[])
_delay = FieldAttribute(isa='int', default=5)
_delegate_to = FieldAttribute(isa='string')
_delegate_facts = FieldAttribute(isa='bool', default=False)
_failed_when = FieldAttribute(isa='list', default=[])
_loop = FieldAttribute(isa='string', private=True, inherit=False)
_loop_args = FieldAttribute(isa='list', private=True, inherit=False)
_loop_control = FieldAttribute(isa='class', class_type=LoopControl, inherit=False)
_name = FieldAttribute(isa='string', default='')
_notify = FieldAttribute(isa='list')
_poll = FieldAttribute(isa='int', default=10)
_register = FieldAttribute(isa='string')
_retries = FieldAttribute(isa='int')
_until = FieldAttribute(isa='list', default=[])
_args = FieldAttribute(isa='dict', default=dict())
_action = FieldAttribute(isa='string')
_async = FieldAttribute(isa='int', default=0)
_changed_when = FieldAttribute(isa='list', default=[])
_delay = FieldAttribute(isa='int', default=5)
_delegate_to = FieldAttribute(isa='string')
_delegate_facts = FieldAttribute(isa='bool', default=False)
_failed_when = FieldAttribute(isa='list', default=[])
_loop = FieldAttribute(isa='string', private=True, inherit=False)
_loop_args = FieldAttribute(isa='list', private=True, inherit=False)
_loop_control = FieldAttribute(isa='class', class_type=LoopControl, inherit=False)
_name = FieldAttribute(isa='string', default='')
_notify = FieldAttribute(isa='list')
_poll = FieldAttribute(isa='int', default=10)
_register = FieldAttribute(isa='string')
_retries = FieldAttribute(isa='int')
_until = FieldAttribute(isa='list', default=[])
def __init__(self, block=None, role=None, task_include=None):
''' constructors a task, without the Task.load classmethod, it will be pretty blank '''
self._role = role
self._role = role
self._parent = None
if task_include:
@ -125,10 +125,10 @@ class Task(Base, Conditional, Taggable, Become):
return ds
elif isinstance(ds, dict):
buf = ""
for (k,v) in iteritems(ds):
for (k, v) in iteritems(ds):
if k.startswith('_'):
continue
buf = buf + "%s=%s " % (k,v)
buf = buf + "%s=%s " % (k, v)
buf = buf.strip()
return buf
@ -186,11 +186,11 @@ class Task(Base, Conditional, Taggable, Become):
if 'cmd' in args:
if args.get('_raw_params', '') != '':
raise AnsibleError("The 'cmd' argument cannot be used when other raw parameters are specified."
" Please put everything in one or the other place.", obj=ds)
" Please put everything in one or the other place.", obj=ds)
args['_raw_params'] = args.pop('cmd')
new_ds['action'] = action
new_ds['args'] = args
new_ds['action'] = action
new_ds['args'] = args
new_ds['delegate_to'] = delegate_to
# we handle any 'vars' specified in the ds here, as we may
@ -203,7 +203,7 @@ class Task(Base, Conditional, Taggable, Become):
else:
new_ds['vars'] = dict()
for (k,v) in iteritems(ds):
for (k, v) in iteritems(ds):
if k in ('action', 'local_action', 'args', 'delegate_to') or k == action or k == 'shell':
# we don't want to re-assign these values, which were
# determined by the ModuleArgsParser() above
@ -216,9 +216,9 @@ class Task(Base, Conditional, Taggable, Become):
# here, and show a deprecation message as we will remove this at
# some point in the future.
if action == 'include' and k not in self._valid_attrs and k not in self.DEPRECATED_ATTRIBUTES:
display.deprecated("Specifying include variables at the top-level of the task is deprecated."
" Please see:\nhttp://docs.ansible.com/ansible/playbooks_roles.html#task-include-files-and-encouraging-reuse\n\n"
" for currently supported syntax regarding included files and variables", version="2.7")
display.deprecated("Specifying include variables at the top-level of the task is deprecated. "
"Please see:\nhttp://docs.ansible.com/ansible/playbooks_roles.html#task-include-files-and-encouraging-reuse\n\n "
"for currently supported syntax regarding included files and variables", version="2.7")
new_ds['vars'][k] = v
else:
new_ds[k] = v

@ -76,4 +76,3 @@ class TaskInclude(Task):
del all_vars['when']
return all_vars

@ -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',
)

@ -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())

@ -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

@ -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

@ -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:

@ -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'):

@ -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):

@ -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,

@ -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

@ -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):

@ -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)

@ -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)

@ -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):

@ -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)

@ -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):

@ -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

@ -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

@ -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)

@ -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(

@ -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

@ -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))

@ -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)

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

Loading…
Cancel
Save