Compare commits

..

31 Commits

Author SHA1 Message Date
847327eb9a Start of work folding threading and forking together 2017-10-04 10:59:06 -05:00
ba0b91b51b Remove git:// urls from docsite and from packaging (#30459)
It's almost always preferable to clone by way of https:// rather than
using the bare git:// protocol. Not only does https:// provide
stronger guarantees it also plays nicer with corporate proxies, etc.
2017-10-03 12:16:25 -07:00
2d70dc7f21 make pipelining actually backwards compatible
restore ssh specific setting the global, in the future these will be separate.
2017-10-03 14:35:05 -04:00
235d139e5d Fixes for facts distribution.py (#31110)
'distribution' facts were being set after checking
the existence of the dist file, and then being set
again with more detail after they were succesfully parsed.

But if the dist file was not succesfully parsed and
matched the required names, the loop continues
without resetting the earlier set facts. This is
how 'Mandriva' would end up being the 'distribution'
file for unrelated cases (it would find /etc/lsb-release,
set distro to 'Mandriva', then fail to parse/match and
continue the loop. If no other checks worked, 'Mandriva'
would stick).

* parse_dist_file_NA should check 'name' not distro for NA

parse_distribution_file_NA was checking the incoming
'distribution' fact to be 'NA', but the fact itself can
be specific at that point ('KDE Neon', for ex) but the
check is really if the 'name' it was passed is NA.

* for matches on OS_RELEASE_ALIAS (ie, 'Archlinux') do
not continue if the dist file content doesn't match. Previously
it had to because of the 'Mandriva' bug mentioned above.

This is a more general fix for #30693 than #30723

Fixes  #30693
Related to #30600
2017-10-03 14:01:40 -04:00
dae0ad1ce6 Fix flush_cache on redis cache
Fix a del on non existent self.cache.

Fixes #31148
2017-10-03 12:54:26 -04:00
278ff19bea Handle vault decrypt --output=- (#31066)
In cli.CLI.unfrack_path callback, special case if the
value of '--output' is '-', and avoid expanding
it to a full path.

vault cli already has special cases for '-', so it
just needs to get the original value to work.

Fixes #30550
2017-10-03 12:02:16 -04:00
cf3414d7d7 set _hosts on access if None (#31111)
set _hosts on access if None to bpyass srlz10n issues to fix #30903
2017-10-03 08:59:05 -07:00
101377768b remove unused ssh pipelining setters
fixes #31125
2017-10-03 09:22:01 -04:00
9b693235f0 Fix backwards compatibility of constants.get_config
get_config would use ConfigManager.get_ini_value which does not
exist. What we are meant to use is
ansible.config.manager.get_ini_config_value and this method does not
expect a list, only a dictionary with a section and a key.
2017-10-03 09:19:04 -04:00
a12a05c219 Fixes #30769 - nxos_vtp_version errors out on N1 images. (#30770)
* Fixes #30769

* add the same fix for 2 more vtp modules
2017-10-03 17:24:14 +05:30
17fbeeb2f0 rhn_channel: PEP8 compliancy and doc fixes (#30912)
This PR includes:
- PEP8 compliancy fixes
- Documentation fixes
2017-10-03 09:50:44 +02:00
4a358b5396 foreman: PEP8 compliancy and doc fixes (#30910)
This PR includes:
- PEP8 compliancy fixes
- Documentation fixes
2017-10-03 09:50:27 +02:00
db70eeb913 Feature/test inventory (#30707)
* [test] move inventory test to right path
* [feat] add unit test for yaml inventory plugin
2017-10-02 23:01:25 -07:00
d0c003ab0f BugFix code breaks, if include_vars dir is file instead of directory (#31157) 2017-10-03 00:00:51 -04:00
89799bbb98 add https_proxy (#31062)
* add https_proxy

* fix indentation

* use http.nonProxyHosts
2017-10-03 00:12:50 +02:00
ef25367353 Fixes #30073: Remove 'Consider hg command' warning. (#31159)
This PR addresses two issues:

1. The hg module was added to command module's check_command list,
so if someone runs hg directly from the command module, the command
module would warn the user "Consider using hg module rather than running hg".

We address this by removing hg from the list.

2. We added a new note to tell users push feature will be addressed
in issue #31156.
2017-10-02 23:33:13 +02:00
Rob
2804a2663a [cloud] Only get rules if listener in elb_application_lb been identified in compare_rules (#30604)
* Only get rules if listener has been identified in compare_rules

* Always cast the listener port to an integer.
2017-10-02 16:57:41 -04:00
46fd083138 LogicalInterconnectGroupFactsModule for HPE OneView (#28847)
* Added support to retrieving LIG resources in HPE OneView

* Fixing copyright header according to review

* Swapping out config for full credentials in parameter for documentation
2017-10-02 16:35:27 -04:00
12a4dca447 win_dotnet_ngen: fix after broken in 2.4 (#31076)
* win_dotnet_ngen: fix after broken in 2.4

* added description to return values
2017-10-03 07:34:00 +11:00
7d74c126a9 EnclosureFactsModule for HPE OneView (#28852)
* Added support to retrieving Enclosures in HPE OneView

- Added unit tests

* Updated version_added to 2.5

* Changing return type of enclosure_script to string

* Fixing copyright header according to review

* Replaced config for credentials in parameters for documentation
2017-10-02 16:32:36 -04:00
67fd98da09 win_msg: added doc about msg limit and included an explicit check for better error handling (#31078) 2017-10-03 07:32:30 +11:00
44f5b2bd25 ansible_tower: fix broken import, reuse tower_argument_spec and documentation fragment (#29115)
* module_utils/ansible_tower: fix broken import

* tower_*: use tower_argument_spec & doc fragment

* tower doc fragment: Ansible requires Python 2.6+

* tower_job_wait: fix broken import (Py3 compat)
2017-10-02 16:21:24 -04:00
af3e8950d6 [fix] issue #30516 : take care about autoremove in upgrade function 2017-10-02 16:19:55 -04:00
6d3cbbfc38 Disable failing vmware_maintenancemode test. 2017-10-02 13:19:17 -07:00
c055795e02 Pin docker simulator versions. 2017-10-02 13:19:17 -07:00
1241d0a3f4 pip: PEP8 compliancy and doc fixes
This PR includes:
- PEP8 compliancy fixes
- Documentation fixes
2017-10-02 16:18:56 -04:00
a71ca66e6e Fix typo in dev_guide/testing 2017-10-02 16:11:08 -04:00
78fd326908 Fix typo in dev_guide/developing_program_flow_modules 2017-10-02 16:10:45 -04:00
9ae159dfa4 Remove robinro as git maintainer 2017-10-02 16:01:58 -04:00
d6737dcdd4 Added info about return_skeleton_generator.py
Added info about return_skeleton_generator.py to hacking/README.md
2017-10-02 15:58:57 -04:00
d313c2d5e9 [cloud] RDS config should be getboolean, as per ec2.ini instructions (#31168) 2017-10-02 15:08:31 -04:00
71 changed files with 1431 additions and 1152 deletions

2
.github/BOTMETA.yml vendored
View File

@ -544,7 +544,7 @@ files:
$modules/remote_management/stacki/stacki_host.py: bbyhuy bsanders
$modules/remote_management/wakeonlan.py: dagwieers
$modules/source_control/bzr.py: andreparames
$modules/source_control/git.py: $team_ansible robinro
$modules/source_control/git.py: $team_ansible
$modules/source_control/git_config.py: djmattyg007
$modules/source_control/github_deploy_key.py: bincyber
$modules/source_control/github_hooks.py: pcgentry

View File

@ -354,7 +354,7 @@ class Ec2Inventory(object):
self.route53_excluded_zones = [a for a in config.get('ec2', 'route53_excluded_zones').split(',') if a]
# Include RDS instances?
self.rds_enabled = config.get('ec2', 'rds')
self.rds_enabled = config.getboolean('ec2', 'rds')
# Include RDS cluster instances?
self.include_rds_clusters = config.getboolean('ec2', 'include_rds_clusters')

View File

@ -277,7 +277,7 @@ substitutions:
- :code:`"<<ANSIBLE_VERSION>>"` is substituted with the Ansible version. In
:ref:`new-style Python modules <flow_python_modules>` under the
:ref:`Ansiballz` frameworkthe proper way is to instead instantiate an
:ref:`Ansiballz` framework the proper way is to instead instantiate an
:class:`AnsibleModule` and then access the version from
:attr:``AnsibleModule.ansible_version``.
- :code:`"<<INCLUDE_ANSIBLE_MODULE_COMPLEX_ARGS>>"` is substituted with

View File

@ -184,7 +184,7 @@ If the PR does not resolve the issue, or if you see any failures from the unit/i
|
| \```
| some output
| StrackTrace
| StackTrace
| some other output
| \```

View File

@ -193,7 +193,7 @@ Deploying From Source Control
Deploy your webapp straight from git::
$ ansible webservers -m git -a "repo=git://foo.example.org/repo.git dest=/srv/myapp version=HEAD"
$ ansible webservers -m git -a "repo=https://foo.example.org/repo.git dest=/srv/myapp version=HEAD"
Since Ansible modules can notify change handlers it is possible to
tell Ansible to run specific tasks when the code is updated, such as

View File

@ -124,7 +124,7 @@ You can also build an RPM yourself. From the root of a checkout or tarball, use
.. code-block:: bash
$ git clone git://github.com/ansible/ansible.git
$ git clone https://github.com/ansible/ansible.git
$ cd ./ansible
$ make rpm
$ sudo rpm -Uvh ./rpm-build/ansible-*.noarch.rpm
@ -263,7 +263,7 @@ Then install Ansible with [1]_::
Or if you are looking for the latest development version::
pip install git+git://github.com/ansible/ansible.git@devel
pip install git+https://github.com/ansible/ansible.git@devel
If you are installing on OS X Mavericks, you may encounter some noise from your compiler. A workaround is to do the following::
@ -305,7 +305,7 @@ To install from source, clone the Ansible git repository:
.. code-block:: bash
$ git clone git://github.com/ansible/ansible.git --recursive
$ git clone https://github.com/ansible/ansible.git --recursive
$ cd ./ansible
Once git has cloned the Ansible repository, setup the Ansible environment:

View File

@ -49,6 +49,12 @@ Use:
$ ./hacking/test-module -m module \
-a '{"parent": {"child": [{"item": "first", "val": "foo"}, {"item": "second", "val": "bar"}]}}'
return_skeleton_generator.py
----------------------------
return_skeleton_generator.py helps in generating the RETURNS section of a module. It takes
JSON output of a module provided either as a file argument or via stdin.
Module-formatter
----------------

View File

@ -406,7 +406,10 @@ class CLI(with_metaclass(ABCMeta, object)):
@staticmethod
def unfrack_path(option, opt, value, parser):
setattr(parser.values, option.dest, unfrackpath(value))
if value != '-':
setattr(parser.values, option.dest, unfrackpath(value))
else:
setattr(parser.values, option.dest, value)
@staticmethod
def base_parser(usage="", output_opts=False, runas_opts=False, meta_opts=False, runtask_opts=False, vault_opts=False, module_opts=False,

View File

@ -56,6 +56,16 @@ ANSIBLE_NOCOWS:
- {key: nocows, section: defaults}
type: boolean
yaml: {key: display.i_am_no_fun}
ANSIBLE_PROCESS_MODEL:
name: Sets the Ansible process model
default: "forking"
description:
- "Ansible supports two process models: forking (default) and threading."
- "The threading model is currently a technology preview."
env: [{name: ANSIBLE_PROCESS_MODEL}]
ini:
- {key: process_model, section: defaults}
yaml: {key: defaults.process_model}
ANSIBLE_PIPELINING:
name: Connection pipelining
default: False
@ -65,9 +75,14 @@ ANSIBLE_PIPELINING:
- This can result in a very significant performance improvement when enabled.
- "However this conflicts with privilege escalation (become). For example, when using 'sudo:' operations you must first
disable 'requiretty' in /etc/sudoers on all managed hosts, which is why it is disabled by default."
env: [{name: ANSIBLE_PIPELINING}]
env:
- name: ANSIBLE_SSH_PIPELINING
- name: ANSIBLE_PIPELINING
ini:
- {key: pipelining, section: connection}
- section: connection
key: pipelining
- section: ssh_connection
key: pipelining
type: boolean
yaml: {key: plugins.connection.pipelining}
ANSIBLE_SSH_ARGS:
@ -115,19 +130,6 @@ ANSIBLE_SSH_EXECUTABLE:
- {key: ssh_executable, section: ssh_connection}
yaml: {key: ssh_connection.ssh_executable}
version_added: "2.2"
ANSIBLE_SSH_PIPELINING:
# TODO: move to ssh plugin
default: False
description:
- Pipelining reduces the number of SSH operations required to execute a module on the remote server,
by executing many Ansible modules without actual file transfer.
- This can result in a very significant performance improvement when enabled.
- "However this conflicts with privilege escalation (become). For example, when using 'sudo:' operations you must first disable 'requiretty' in /etc/sudoers on all managed hosts, which is why it is disabled by default."
env: [{name: ANSIBLE_SSH_PIPELINING}]
ini:
- {key: pipelining, section: ssh_connection}
type: boolean
yaml: {key: ssh_connection.pipelining}
ANSIBLE_SSH_RETRIES:
# TODO: move to ssh plugin
default: 0

View File

@ -15,7 +15,7 @@ from string import ascii_letters, digits
from ansible.module_utils._text import to_text
from ansible.module_utils.parsing.convert_bool import boolean, BOOLEANS_TRUE
from ansible.module_utils.six import string_types
from ansible.config.manager import ConfigManager, ensure_type
from ansible.config.manager import ConfigManager, ensure_type, get_ini_config_value
def _deprecated(msg):
@ -43,7 +43,7 @@ def get_config(parser, section, key, env_var, default_value, value_type=None, ex
value = os.environ.get(env_var, None)
if value is None:
try:
value = config.get_ini_config(parser, [{'key': key, 'section': section}])
value = get_ini_config_value(parser, {'key': key, 'section': section})
except:
pass
if value is None:

View File

@ -0,0 +1,35 @@
# (c) 2017, Red Hat, Inc. <support@ansible.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
from ansible.plugins.loader import action_loader, connection_loader, filter_loader, lookup_loader, module_loader, test_loader
class SharedPluginLoaderObj:
'''
A simple object to make pass the various plugin loaders to
the forked processes over the queue easier
'''
def __init__(self):
self.action_loader = action_loader
self.connection_loader = connection_loader
self.filter_loader = filter_loader
self.lookup_loader = lookup_loader
self.module_loader = module_loader
self.test_loader = test_loader

View File

@ -299,13 +299,14 @@ class TaskExecutor:
templar = Templar(loader=self._loader, shared_loader_obj=self._shared_loader_obj, variables=self._job_vars)
res['_ansible_item_label'] = templar.template(label)
self._rslt_q.put_result(
self._rslt_q.put(
TaskResult(
self._host,
self._task,
self._host.name,
self._task._uuid,
res,
task_fields=self._task.dump_attrs(),
),
block=False,
)
results.append(res)
del task_vars[loop_var]
@ -590,7 +591,7 @@ class TaskExecutor:
result['_ansible_retry'] = True
result['retries'] = retries
display.debug('Retrying task, attempt %d of %d' % (attempt, retries))
self._rslt_q.put_result(TaskResult(self._host, self._task, result, task_fields=self._task.dump_attrs()))
self._rslt_q.put(TaskResult(self._host.name, self._task._uuid, result, task_fields=self._task.dump_attrs()), block=False)
time.sleep(delay)
else:
if retries > 1:

View File

@ -19,22 +19,27 @@
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import threading
import multiprocessing
import os
import tempfile
import threading
import time
from collections import deque
from ansible import constants as C
from ansible.errors import AnsibleError
from ansible.executor.play_iterator import PlayIterator
from ansible.executor.process.worker import WorkerProcess
from ansible.executor.process.threading import run_worker
from ansible.executor.shared_plugin_loader import SharedPluginLoaderObj
from ansible.executor.stats import AggregateStats
from ansible.module_utils.six import string_types
from ansible.module_utils.six.moves import queue as Queue
from ansible.module_utils._text import to_text
from ansible.playbook.block import Block
from ansible.playbook.play_context import PlayContext
from ansible.plugins.loader import action_loader, connection_loader, filter_loader, test_loader, lookup_loader, callback_loader, strategy_loader, module_loader
from ansible.plugins.loader import callback_loader, strategy_loader, module_loader
from ansible.plugins.callback import CallbackBase
from ansible.template import Templar
from ansible.utils.helpers import pct_to_int
@ -50,22 +55,25 @@ except ImportError:
__all__ = ['TaskQueueManager']
class ResultsSentinel:
pass
# TODO: this should probably be in the plugins/__init__.py, with
# a smarter mechanism to set all of the attributes based on
# the loaders created there
class SharedPluginLoaderObj:
'''
A simple object to make pass the various plugin loaders to
the forked processes over the queue easier
'''
def __init__(self):
self.action_loader = action_loader
self.connection_loader = connection_loader
self.filter_loader = filter_loader
self.test_loader = test_loader
self.lookup_loader = lookup_loader
self.module_loader = module_loader
_sentinel = ResultsSentinel()
def results_thread_main(tqm):
while True:
try:
result = tqm._final_q.get()
if isinstance(result, ResultsSentinel):
break
else:
tqm._results_lock.acquire()
tqm._res_queue.append(result)
tqm._results_lock.release()
except (IOError, EOFError):
break
except Queue.Empty:
pass
class TaskQueueManager:
@ -120,47 +128,58 @@ class TaskQueueManager:
self._failed_hosts = dict()
self._unreachable_hosts = dict()
# A temporary file (opened pre-fork) used by connection
# plugins for inter-process locking.
self._connection_lockfile = tempfile.TemporaryFile()
self._job_queue = deque()
self._job_queue_lock = threading.Lock()
# the final results queue we'll use for both forking and threading
self._res_queue = deque()
self._res_queue_lock = threading.Lock()
self._res_ready = threading.Event()
def _put_in_queue(self, data, queue, lock):
lock.acquire()
queue.appendleft(data)
lock.release()
def _pop_off_queue(self, queue, lock):
try:
data = None
lock.acquire()
data = queue.pop()
except:
pass
finally:
lock.release()
return data
def put_job(self, data):
self._put_in_queue(data, self._job_queue, self._job_queue_lock)
def get_job(self):
return self._pop_off_queue(self._job_queue, self._job_queue_lock)
def put_result(self, data):
self._put_in_queue(data, self._res_queue, self._res_queue_lock)
self._res_ready.set()
def get_result(self):
return self._pop_off_queue(self._res_queue, self._res_queue_lock)
# A temporary file (opened pre-fork) used by connection
# plugins for inter-process locking.
self._connection_lockfile = tempfile.TemporaryFile()
def _initialize_processes(self, num):
if C.ANSIBLE_PROCESS_MODEL == 'forking':
self._final_q = multiprocessing.Queue()
self._job_queue = None
self._job_queue_lock = None
self.put_job = self._forked_put_job
self.get_job = self._forked_get_job
self.put_result = self._forked_put_result
self.get_result = self._forked_get_result
self._cleanup_processes = self._cleanup_forked_processes
self._initialize_forked_processes(num)
# create the result processing thread for reading results in the background
self._results_lock = threading.Condition(threading.Lock())
self._results_thread = threading.Thread(target=results_thread_main, args=(self,))
self._results_thread.daemon = True
self._results_thread.start()
elif C.ANSIBLE_PROCESS_MODEL == 'threading':
self._job_queue = deque()
self._job_queue_lock = threading.Lock()
self.put_job = self._threaded_put_job
self.get_job = self._threaded_get_job
self.put_result = self._threaded_put_result
self.get_result = self._threaded_get_result
self._cleanup_processes = self._cleanup_threaded_processes
self._initialize_threaded_processes(num)
else:
self._cleanup_processes = self._cleanup_dummy
raise AnsibleError(
'Invalid process model specified: "%s". ' \
'The process model must be set to either "forking" or "threading"'
)
def _initialize_forked_processes(self, num):
self._workers = []
self._cur_worker = 0
for i in range(num):
self._workers.append([None, None])
def _initialize_threaded_processes(self, num):
# FIXME: do we need a global lock for workers here instead of a per-worker?
self._workers = []
@ -169,6 +188,8 @@ class TaskQueueManager:
shared_loader_obj = SharedPluginLoaderObj()
for i in range(num):
rslt_q = multiprocessing.Queue()
self._workers.append([None, rslt_q])
w_thread = threading.Thread(target=run_worker, args=(self, shared_loader_obj))
w_thread.start()
w_lock = threading.Lock()
@ -366,16 +387,31 @@ class TaskQueueManager:
for host_name in iterator.get_failed_hosts():
self._failed_hosts[host_name] = True
strategy.cleanup()
self._cleanup_processes()
return play_return
def cleanup(self):
display.debug("RUNNING CLEANUP")
self.terminate()
if hasattr(self, '_final_q'):
self._final_q.put(_sentinel)
self._results_thread.join()
self._final_q.close()
self._cleanup_processes()
def _cleanup_processes(self):
def _cleanup_dummy(self):
return
def _cleanup_forked_processes(self):
if hasattr(self, '_workers'):
for (worker_prc, _) in self._workers:
if worker_prc and worker_prc.is_alive():
try:
worker_prc.terminate()
except AttributeError:
pass
def _cleanup_threaded_processes(self):
if hasattr(self, '_workers'):
for (w_thread, w_lock) in self._workers:
if w_thread and not w_thread.is_alive():
@ -394,7 +430,7 @@ class TaskQueueManager:
return self._loader
def get_workers(self):
return self._workers[:]
return self._workers
def terminate(self):
self._terminated = True
@ -436,3 +472,78 @@ class TaskQueueManager:
from traceback import format_tb
from sys import exc_info
display.vvv('Callback Exception: \n' + ' '.join(format_tb(exc_info()[2])))
# helpers for forking
def _forked_put_job(self, data):
try:
(host, task, play_context, task_vars) = data
# create a dummy object with plugin loaders set as an easier
# way to share them with the forked processes
shared_loader_obj = SharedPluginLoaderObj()
queued = False
starting_worker = self._cur_worker
while True:
(worker_prc, rslt_q) = self._workers[self._cur_worker]
if worker_prc is None or not worker_prc.is_alive():
worker_prc = WorkerProcess(self._final_q, task_vars, host, task, play_context, self._loader, self._variable_manager, shared_loader_obj)
self._workers[self._cur_worker][0] = worker_prc
worker_prc.start()
display.debug("worker is %d (out of %d available)" % (self._cur_worker + 1, len(self._workers)))
queued = True
self._cur_worker += 1
if self._cur_worker >= len(self._workers):
self._cur_worker = 0
if queued:
break
elif self._cur_worker == starting_worker:
time.sleep(0.0001)
return True
except (EOFError, IOError, AssertionError) as e:
# most likely an abort
display.debug("got an error while queuing: %s" % e)
return False
def _forked_get_job(self):
pass
def _forked_put_result(self):
pass
def _forked_get_result(self):
return self._pop_off_queue(self._res_queue, self._res_queue_lock)
# helpers for threading
def _put_in_queue(self, data, queue, lock):
lock.acquire()
queue.appendleft(data)
lock.release()
def _pop_off_queue(self, queue, lock):
try:
data = None
lock.acquire()
data = queue.pop()
except:
pass
finally:
lock.release()
return data
def _threaded_put_job(self, data):
self._put_in_queue(data, self._job_queue, self._job_queue_lock)
return True
def _threaded_get_job(self):
return self._pop_off_queue(self._job_queue, self._job_queue_lock)
def _threaded_put_result(self, data):
self._put_in_queue(data, self._res_queue, self._res_queue_lock)
self._res_ready.set()
return True
def _threaded_get_result(self):
return self._pop_off_queue(self._res_queue, self._res_queue_lock)

View File

@ -18,7 +18,6 @@ from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from ansible.errors import AnsibleError
from ansible.utils.vars import combine_vars
class Group:
@ -31,7 +30,7 @@ class Group:
self.depth = 0
self.name = name
self.hosts = []
self._hosts = set()
self._hosts = None
self.vars = {}
self.child_groups = []
self.parent_groups = []
@ -72,9 +71,8 @@ class Group:
self.name = data.get('name')
self.vars = data.get('vars', dict())
self.depth = data.get('depth', 0)
self.hosts = data.get('hosts', {})
self._hosts = set(self.hosts)
self.hosts = data.get('hosts', [])
self._hosts = None
parent_groups = data.get('parent_groups', [])
for parent_data in parent_groups:
@ -82,6 +80,12 @@ class Group:
g.deserialize(parent_data)
self.parent_groups.append(g)
@property
def host_names(self):
if self._hosts is None:
self._hosts = set(self.hosts)
return self._hosts
def get_name(self):
return self.name
@ -119,7 +123,7 @@ class Group:
raise AnsibleError("The group named '%s' has a recursive dependency loop." % self.name)
def add_host(self, host):
if host.name not in self._hosts:
if host.name not in self.host_names:
self.hosts.append(host)
self._hosts.add(host.name)
host.add_group(self)
@ -127,7 +131,7 @@ class Group:
def remove_host(self, host):
if host.name in self._hosts:
if host.name in self.host_names:
self.hosts.remove(host)
self._hosts.remove(host.name)
host.remove_group(self)

View File

@ -28,9 +28,14 @@
import os
import tower_cli.utils.exceptions as exc
from tower_cli.utils import parser
from tower_cli.api import client
try:
import tower_cli.utils.exceptions as exc
from tower_cli.utils import parser
from tower_cli.api import client
HAS_TOWER_CLI = True
except ImportError:
HAS_TOWER_CLI = False
def tower_auth_config(module):

View File

@ -113,11 +113,9 @@ class DistributionFiles:
# only the distribution name is set, the version is assumed to be correct from platform.dist()
if self.SEARCH_STRING[name] in dist_file_content:
# this sets distribution=RedHat if 'Red Hat' shows up in data
# self.facts['distribution'] = name
dist_file_dict['distribution'] = name
else:
# this sets distribution to what's in the data, e.g. CentOS, Scientific, ...
# self.facts['distribution'] = dist_file_content.split()[0]
dist_file_dict['distribution'] = dist_file_content.split()[0]
return True, dist_file_dict
@ -126,15 +124,14 @@ class DistributionFiles:
if self.OS_RELEASE_ALIAS[name] in dist_file_content:
dist_file_dict['distribution'] = name
return True, dist_file_dict
return False, dist_file_dict
# call a dedicated function for parsing the file content
# TODO: replace with a map or a class
try:
# FIXME: most of these dont actually look at the dist file contents, but random other stuff
distfunc_name = 'parse_distribution_file_' + name
# print('distfunc_name: %s' % distfunc_name)
distfunc = getattr(self, distfunc_name)
# print('distfunc: %s' % distfunc)
parsed, dist_file_dict = distfunc(name, dist_file_content, path, collected_facts)
return parsed, dist_file_dict
except AttributeError as exc:
@ -180,31 +177,29 @@ class DistributionFiles:
# /etc/os-release with a different name
if has_dist_file and allow_empty:
dist_file_facts['distribution'] = name
dist_file_facts['distribution_file_path'] = path
dist_file_facts['distribution_file_variety'] = name
break
if not has_dist_file:
# keep looking
continue
# first valid os dist file we find we count
# FIXME: coreos and a few other bits expect this
# self.facts['distribution'] = name
dist_file_facts['distribution'] = name
dist_file_facts['distribution_file_variety'] = name
dist_file_facts['distribution_file_path'] = path
parsed_dist_file, parsed_dist_file_facts = self._parse_dist_file(name, dist_file_content, path, dist_file_facts)
dist_file_facts['distribution_file_parsed'] = parsed_dist_file
# finally found the right os dit file and were able to parse it
# finally found the right os dist file and were able to parse it
if parsed_dist_file:
dist_file_facts['distribution'] = name
dist_file_facts['distribution_file_path'] = path
# distribution and file_variety are the same here, but distribution
# will be changed/mapped to a more specific name.
# ie, dist=Fedora, file_variety=RedHat
dist_file_facts['distribution_file_variety'] = name
dist_file_facts['distribution_file_parsed'] = parsed_dist_file
dist_file_facts.update(parsed_dist_file_facts)
break
return dist_file_facts
# distribution_facts.update(dist_file_facts)
# return distribution_facts
# TODO: FIXME: split distro file parsing into its own module or class
def parse_distribution_file_Slackware(self, name, data, path, collected_facts):
@ -338,7 +333,7 @@ class DistributionFiles:
na_facts = {}
for line in data.splitlines():
distribution = re.search("^NAME=(.*)", line)
if distribution and collected_facts['distribution'] == 'NA':
if distribution and name == 'NA':
na_facts['distribution'] = distribution.group(1).strip('"')
version = re.search("^VERSION=(.*)", line)
if version and collected_facts['distribution_version'] == 'NA':
@ -532,11 +527,8 @@ class Distribution(object):
def get_distribution_SunOS(self):
sunos_facts = {}
# print('platform.release: %s' % distribution_release)
data = get_file_content('/etc/release').splitlines()[0]
# print('get_file_content: data=%s' % data)
if 'Solaris' in data:
ora_prefix = ''
if 'Oracle Solaris' in data:
@ -550,8 +542,6 @@ class Distribution(object):
uname_v = get_uname_version(self.module)
distribution_version = None
# print('uname_v: %s' % uname_v)
if 'SmartOS' in data:
sunos_facts['distribution'] = 'SmartOS'
if _file_exists('/etc/product'):
@ -567,7 +557,6 @@ class Distribution(object):
sunos_facts['distribution'] = 'Nexenta'
distribution_version = data.split()[-1].lstrip('v')
# print('sunos_facts: %s' % sunos_facts)
if sunos_facts.get('distribution', '') in ('SmartOS', 'OpenIndiana', 'OmniOS', 'Nexenta'):
sunos_facts['distribution_release'] = data.strip()
if distribution_version is not None:

View File

@ -619,6 +619,8 @@ def compare_listeners(connection, module, current_listeners, new_listeners, purg
Compare listeners and return listeners to add, listeners to modify and listeners to remove
Listeners are compared based on port
:param connection: ELBv2 boto3 connection
:param module: Ansible module object
:param current_listeners:
:param new_listeners:
:param purge_listeners:
@ -659,10 +661,10 @@ def compare_rules(connection, module, current_listeners, listener):
Compare rules and return rules to add, rules to modify and rules to remove
Rules are compared based on priority
:param connection:
:param module:
:param current_listeners:
:param listener:
:param connection: ELBv2 boto3 connection
:param module: Ansible module object
:param current_listeners: list of listeners currently associated with the ELB
:param listener: dict object of a listener passed by the user
:return:
"""
@ -672,8 +674,11 @@ def compare_rules(connection, module, current_listeners, listener):
listener['ListenerArn'] = current_listener['ListenerArn']
break
# Get rules for the listener
current_rules = get_listener_rules(connection, module, listener['ListenerArn'])
# If the listener exists (i.e. has an ARN) get rules for the listener
if 'ListenerArn' in listener:
current_rules = get_listener_rules(connection, module, listener['ListenerArn'])
else:
current_rules = []
rules_to_modify = []
rules_to_delete = []
@ -997,6 +1002,9 @@ def main():
if key not in ['Protocol', 'Port', 'SslPolicy', 'Certificates', 'DefaultActions', 'Rules']:
module.fail_json(msg="listeners parameter contains invalid dict keys. Should be one of 'Protocol', "
"'Port', 'SslPolicy', 'Certificates', 'DefaultActions', 'Rules'.")
# Make sure Port is always an integer
elif key == 'Port':
listener[key] = int(listener[key])
if not HAS_BOTO3:
module.fail_json(msg='boto3 required for this module')

View File

@ -124,7 +124,7 @@ def check_command(module, commandline):
arguments = {'chown': 'owner', 'chmod': 'mode', 'chgrp': 'group',
'ln': 'state=link', 'mkdir': 'state=directory',
'rmdir': 'state=absent', 'rm': 'state=absent', 'touch': 'state=touch'}
commands = {'hg': 'hg', 'curl': 'get_url or uri', 'wget': 'get_url or uri',
commands = {'curl': 'get_url or uri', 'wget': 'get_url or uri',
'svn': 'subversion', 'service': 'service',
'mount': 'mount', 'rpm': 'yum, dnf or zypper', 'yum': 'yum', 'apt-get': 'apt',
'tar': 'unarchive', 'unzip': 'unarchive', 'sed': 'template or lineinfile',

View File

@ -149,10 +149,13 @@ def get_vtp_config(module):
def get_vtp_password(module):
command = 'show vtp password'
body = execute_show_command(command, module)[0]
password = body['passwd']
if password:
return str(password)
else:
try:
password = body['passwd']
if password:
return str(password)
else:
return ""
except TypeError:
return ""

View File

@ -180,10 +180,13 @@ def get_vtp_config(module):
def get_vtp_password(module):
command = 'show vtp password'
body = execute_show_command(command, module)[0]
password = body['passwd']
if password:
return str(password)
else:
try:
password = body['passwd']
if password:
return str(password)
else:
return ""
except TypeError:
return ""

View File

@ -147,10 +147,13 @@ def get_vtp_config(module):
def get_vtp_password(module):
command = 'show vtp password'
body = execute_show_command(command, module)[0]
password = body['passwd']
if password:
return str(password)
else:
try:
password = body['passwd']
if password:
return str(password)
else:
return ""
except TypeError:
return ""

View File

@ -1,22 +1,20 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2012, Matt Wright <matt@nobien.net>
# Copyright: (c) 2012, Matt Wright <matt@nobien.net>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'core'}
DOCUMENTATION = '''
---
module: pip
short_description: Manages Python library dependencies.
short_description: Manages Python library dependencies
description:
- "Manage Python library dependencies. To use this module, one of the following keys is required: C(name)
or C(requirements)."
@ -26,19 +24,13 @@ options:
description:
- The name of a Python library to install or the url of the remote package.
- As of 2.2 you can supply a list of names.
required: false
default: null
version:
description:
- The version number to install of the Python library specified in the I(name) parameter
required: false
default: null
- The version number to install of the Python library specified in the I(name) parameter.
requirements:
description:
- The path to a pip requirements file, which should be local to the remote system.
File can be specified as a relative path if using the chdir option.
required: false
default: null
virtualenv:
description:
- An optional path to a I(virtualenv) directory to install into.
@ -47,62 +39,51 @@ options:
If the virtualenv does not exist, it will be created before installing
packages. The optional virtualenv_site_packages, virtualenv_command,
and virtualenv_python options affect the creation of the virtualenv.
required: false
default: null
virtualenv_site_packages:
version_added: "1.0"
description:
- Whether the virtual environment will inherit packages from the
global site-packages directory. Note that if this setting is
changed on an already existing virtual environment it will not
have any effect, the environment must be deleted and newly
created.
required: false
type: bool
default: "no"
choices: [ "yes", "no" ]
version_added: "1.0"
virtualenv_command:
version_added: "1.1"
description:
- The command or a pathname to the command to create the virtual
environment with. For example C(pyvenv), C(virtualenv),
C(virtualenv2), C(~/bin/virtualenv), C(/usr/local/bin/virtualenv).
required: false
default: virtualenv
version_added: "1.1"
virtualenv_python:
version_added: "2.0"
description:
- The Python executable used for creating the virtual environment.
For example C(python3.5), C(python2.7). When not specified, the
Python version used to run the ansible module is used. This parameter
should not be used when C(virtualenv_command) is using C(pyvenv) or
the C(-m venv) module.
required: false
default: null
version_added: "2.0"
state:
description:
- The state of module
- The 'forcereinstall' option is only available in Ansible 2.1 and above.
required: false
choices: [ absent, forcereinstall, latest, present ]
default: present
choices: [ "present", "absent", "latest", "forcereinstall" ]
extra_args:
description:
- Extra arguments passed to pip.
required: false
default: null
version_added: "1.0"
editable:
description:
- Pass the editable flag.
required: false
default: false
type: bool
default: 'no'
version_added: "2.0"
chdir:
description:
- cd into this directory before running the command
version_added: "1.3"
required: false
default: null
executable:
description:
- The explicit executable or a pathname to the executable to be used to
@ -113,8 +94,6 @@ options:
By default, it will take the appropriate version for the python interpreter
use by ansible, e.g. pip3 on python 3, and pip2 or pip on python 2.
version_added: "1.3"
required: false
default: null
umask:
description:
- The system umask to apply before installing the pip package. This is
@ -123,17 +102,17 @@ options:
packages which are to be used by all users. Note that this requires you
to specify desired umask mode in octal, with a leading 0 (e.g., 0077).
version_added: "2.1"
required: false
default: null
notes:
- Please note that virtualenv (U(http://www.virtualenv.org/)) must be
installed on the remote host if the virtualenv parameter is specified and
the virtualenv needs to be created.
- By default, this module will use the appropriate version of pip for the
interpreter used by ansible (e.g. pip3 when using python 3, pip2 otherwise)
requirements: [ "virtualenv", "pip" ]
author: "Matt Wright (@mattupstate)"
requirements:
- pip
- virtualenv
author:
- Matt Wright (@mattupstate)
'''
EXAMPLES = '''
@ -307,8 +286,8 @@ def _get_pip(module, env=None, executable=None):
else:
# For-else: Means that we did not break out of the loop
# (therefore, that pip was not found)
module.fail_json(msg='Unable to find any of %s to use. pip'
' needs to be installed.' % ', '.join(candidate_pip_basenames))
module.fail_json(msg='Unable to find any of %s to use. pip' +
' needs to be installed.' % ', '.join(candidate_pip_basenames))
else:
# If we're using a virtualenv we must use the pip from the
# virtualenv
@ -322,10 +301,9 @@ def _get_pip(module, env=None, executable=None):
else:
# For-else: Means that we did not break out of the loop
# (therefore, that pip was not found)
module.fail_json(msg='Unable to find pip in the virtualenv,'
' %s, under any of these names: %s. Make sure pip is'
' present in the virtualenv.' % (env,
', '.join(candidate_pip_basenames)))
module.fail_json(msg='Unable to find pip in the virtualenv, %s, ' % env +
'under any of these names: %s. ' % (', '.join(candidate_pip_basenames)) +
'Make sire pip is present in the virtualenv.')
return pip
@ -374,24 +352,24 @@ def main():
module = AnsibleModule(
argument_spec=dict(
state=dict(default='present', choices=state_map.keys()),
state=dict(type='str', default='present', choices=state_map.keys()),
name=dict(type='list'),
version=dict(type='str'),
requirements=dict(type='str'),
virtualenv=dict(type='path'),
virtualenv_site_packages=dict(default=False, type='bool'),
virtualenv_command=dict(default='virtualenv', type='path'),
virtualenv_site_packages=dict(type='bool', default=False),
virtualenv_command=dict(type='path', default='virtualenv'),
virtualenv_python=dict(type='str'),
use_mirrors=dict(default=True, type='bool'),
use_mirrors=dict(type='bool', default=True),
extra_args=dict(type='str'),
editable=dict(default=False, type='bool'),
editable=dict(type='bool', default=False),
chdir=dict(type='path'),
executable=dict(type='path'),
umask=dict(type='str'),
),
required_one_of=[['name', 'requirements']],
mutually_exclusive=[['name', 'requirements'], ['executable', 'virtualenv']],
supports_check_mode=True
supports_check_mode=True,
)
state = module.params['state']

View File

@ -722,7 +722,13 @@ def cleanup(m, purge=False, force=False, operation=None,
def upgrade(m, mode="yes", force=False, default_release=None,
use_apt_get=False,
dpkg_options=expand_dpkg_options(DPKG_OPTIONS)):
dpkg_options=expand_dpkg_options(DPKG_OPTIONS), autoremove=None):
if autoremove:
autoremove = '--auto-remove'
else:
autoremove = ''
if m.check_mode:
check_arg = '--simulate'
else:
@ -741,7 +747,7 @@ def upgrade(m, mode="yes", force=False, default_release=None,
else:
if use_apt_get:
apt_cmd = APT_GET_CMD
upgrade_command = "upgrade --with-new-pkgs --autoremove"
upgrade_command = "upgrade --with-new-pkgs %s" % (autoremove)
else:
# aptitude safe-upgrade # mode=yes # default
apt_cmd = APTITUDE_CMD
@ -975,7 +981,7 @@ def main():
force_yes = p['force']
if p['upgrade']:
upgrade(module, p['upgrade'], force_yes, p['default_release'], use_apt_get, dpkg_options)
upgrade(module, p['upgrade'], force_yes, p['default_release'], use_apt_get, dpkg_options, autoremove)
if p['deb']:
if p['state'] != 'present':
@ -995,7 +1001,7 @@ def main():
if latest and all_installed:
if packages:
module.fail_json(msg='unable to install additional packages when ugrading all installed packages')
upgrade(module, 'yes', force_yes, p['default_release'], use_apt_get, dpkg_options)
upgrade(module, 'yes', force_yes, p['default_release'], use_apt_get, dpkg_options, autoremove)
if packages:
for package in packages:

View File

@ -1,26 +1,24 @@
#!/usr/bin/python
# (c) Vincent Van de Kussen
#
# Copyright: (c) Vincent Van de Kussen
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'core'}
DOCUMENTATION = '''
---
module: rhn_channel
short_description: Adds or removes Red Hat software channels
description:
- Adds or removes Red Hat software channels
- Adds or removes Red Hat software channels.
version_added: "1.1"
author: "Vincent Van der Kussen (@vincentvdk)"
author:
- Vincent Van der Kussen (@vincentvdk)
notes:
- This module fetches the system id from RHN.
- This module doesn't support I(check_mode).
@ -43,11 +41,11 @@ options:
required: true
user:
description:
- RHN/Satellite login
- RHN/Satellite login.
required: true
password:
description:
- RHN/Satellite password
- RHN/Satellite password.
required: true
'''
@ -58,14 +56,13 @@ EXAMPLES = '''
url: https://rhn.redhat.com/rpc/api
user: rhnuser
password: guessme
delegate_to: localhost
'''
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.six.moves import xmlrpc_client
# ------------------------------------------------------- #
def get_systemid(client, session, sysname):
systems = client.system.listUserSystems(session)
for system in systems:
@ -74,21 +71,18 @@ def get_systemid(client, session, sysname):
idd = int(idres)
return idd
# ------------------------------------------------------- #
def subscribe_channels(channelname, client, session, sysname, sys_id):
channels = base_channels(client, session, sys_id)
channels.append(channelname)
return client.system.setChildChannels(session, sys_id, channels)
# ------------------------------------------------------- #
def unsubscribe_channels(channelname, client, session, sysname, sys_id):
channels = base_channels(client, session, sys_id)
channels.remove(channelname)
return client.system.setChildChannels(session, sys_id, channels)
# ------------------------------------------------------- #
def base_channels(client, session, sys_id):
basechan = client.channel.software.listSystemChannels(session, sys_id)
@ -98,19 +92,17 @@ def base_channels(client, session, sys_id):
chans = [item['channel_label'] for item in basechan]
return chans
# ------------------------------------------------------- #
def main():
module = AnsibleModule(
argument_spec = dict(
state = dict(default='present', choices=['present', 'absent']),
name = dict(required=True),
sysname = dict(required=True),
url = dict(required=True),
user = dict(required=True),
password = dict(required=True, aliases=['pwd'], no_log=True),
argument_spec=dict(
state=dict(type='str', default='present', choices=['present', 'absent']),
name=dict(type='str', required=True),
sysname=dict(type='str', required=True),
url=dict(type='str', required=True),
user=dict(type='str', required=True),
password=dict(type='str', required=True, aliases=['pwd'], no_log=True),
)
)
@ -140,7 +132,7 @@ def main():
module.exit_json(changed=True, msg="Channel %s added" % channelname)
if state == 'absent':
if not channelname in chans:
if channelname not in chans:
module.exit_json(changed=False, msg="Not subscribed to channel %s." % channelname)
else:
unsubscribe_channels(channelname, client, session, systname, sys_id)

View File

@ -1,62 +1,62 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2016, Eric D Helms <ericdhelms@gmail.com>
# Copyright: (c) 2016, Eric D Helms <ericdhelms@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: foreman
short_description: Manage Foreman Resources
description:
- Allows the management of Foreman resources inside your Foreman server
- Allows the management of Foreman resources inside your Foreman server.
version_added: "2.3"
author: "Eric D Helms (@ehelms)"
author:
- Eric D Helms (@ehelms)
requirements:
- "nailgun >= 0.28.0"
- "python >= 2.6"
- nailgun >= 0.28.0
- python >= 2.6
- datetime
options:
server_url:
description:
- URL of Foreman server
- URL of Foreman server.
required: true
username:
description:
- Username on Foreman server
- Username on Foreman server.
required: true
password:
description:
- Password for user accessing Foreman server
- Password for user accessing Foreman server.
required: true
entity:
description:
- The Foreman resource that the action will be performed on (e.g. organization, host)
- The Foreman resource that the action will be performed on (e.g. organization, host).
required: true
params:
description:
- Parameters associated to the entity resource to set or edit in dictionary format (e.g. name, description)
- Parameters associated to the entity resource to set or edit in dictionary format (e.g. name, description).
required: true
'''
EXAMPLES = '''
- name: "Create CI Organization"
local_action:
module: foreman
username: "admin"
password: "admin"
server_url: "https://fakeserver.com"
entity: "organization"
params:
name: "My Cool New Organization"
- name: Create CI Organization
foreman:
username: admin
password: admin
server_url: https://fakeserver.com
entity: organization
params:
name: My Cool New Organization
delegate_to: localhost
'''
RETURN = '''# '''
@ -86,8 +86,8 @@ class NailGun(object):
if len(response) == 1:
return response[0]
else:
return None
return None
def organization(self, params):
name = params['name']
@ -103,17 +103,18 @@ class NailGun(object):
return True
def main():
module = AnsibleModule(
argument_spec=dict(
server_url=dict(required=True),
username=dict(required=True, no_log=True),
password=dict(required=True, no_log=True),
entity=dict(required=True, no_log=False),
verify_ssl=dict(required=False, type='bool', default=False),
params=dict(required=True, no_log=True, type='dict'),
server_url=dict(type='str', required=True),
username=dict(type='str', required=True, no_log=True),
password=dict(type='str', required=True, no_log=True),
entity=dict(type='str', required=True),
verify_ssl=dict(type='bool', default=False),
params=dict(type='dict', required=True, no_log=True),
),
supports_check_mode=True
supports_check_mode=True,
)
if not HAS_NAILGUN_PACKAGE:

View File

@ -1,49 +1,49 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# (c) 2016, Eric D Helms <ericdhelms@gmail.com>
# Copyright: (c) 2016, Eric D Helms <ericdhelms@gmail.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: katello
short_description: Manage Katello Resources
description:
- Allows the management of Katello resources inside your Foreman server
- Allows the management of Katello resources inside your Foreman server.
version_added: "2.3"
author: "Eric D Helms (@ehelms)"
author:
- Eric D Helms (@ehelms)
requirements:
- "nailgun >= 0.28.0"
- "python >= 2.6"
- nailgun >= 0.28.0
- python >= 2.6
- datetime
options:
server_url:
description:
- URL of Foreman server
- URL of Foreman server.
required: true
username:
description:
- Username on Foreman server
- Username on Foreman server.
required: true
password:
description:
- Password for user accessing Foreman server
- Password for user accessing Foreman server.
required: true
entity:
description:
- The Foreman resource that the action will be performed on (e.g. organization, host)
- The Foreman resource that the action will be performed on (e.g. organization, host).
required: true
params:
description:
- Parameters associated to the entity resource to set or edit in dictionary format (e.g. name, description)
- Parameters associated to the entity resource to set or edit in dictionary format (e.g. name, description).
required: true
'''
@ -51,79 +51,79 @@ EXAMPLES = '''
---
# Simple Example:
- name: "Create Product"
local_action:
module: katello
username: "admin"
password: "admin"
server_url: "https://fakeserver.com"
entity: "product"
- name: Create Product
katello:
username: admin
password: admin
server_url: https://fakeserver.com
entity: product
params:
name: "Centos 7"
name: Centos 7
delegate_to: localhost
# Abstraction Example:
# katello.yml
---
- name: "{{ name }}"
local_action:
module: katello
username: "admin"
password: "admin"
server_url: "https://fakeserver.com"
katello:
username: admin
password: admin
server_url: https://fakeserver.com
entity: "{{ entity }}"
params: "{{ params }}"
delegate_to: localhost
# tasks.yml
---
- include: katello.yml
vars:
name: "Create Dev Environment"
entity: "lifecycle_environment"
name: Create Dev Environment
entity: lifecycle_environment
params:
name: "Dev"
prior: "Library"
organization: "Default Organization"
name: Dev
prior: Library
organization: Default Organization
- include: katello.yml
vars:
name: "Create Centos Product"
entity: "product"
name: Create Centos Product
entity: product
params:
name: "Centos 7"
organization: "Default Organization"
name: Centos 7
organization: Default Organization
- include: katello.yml
vars:
name: "Create 7.2 Repository"
entity: "repository"
name: Create 7.2 Repository
entity: repository
params:
name: "Centos 7.2"
product: "Centos 7"
organization: "Default Organization"
content_type: "yum"
url: "http://mirror.centos.org/centos/7/os/x86_64/"
name: Centos 7.2
product: Centos 7
organization: Default Organization
content_type: yum
url: http://mirror.centos.org/centos/7/os/x86_64/
- include: katello.yml
vars:
name: "Create Centos 7 View"
entity: "content_view"
name: Create Centos 7 View
entity: content_view
params:
name: "Centos 7 View"
organization: "Default Organization"
name: Centos 7 View
organization: Default Organization
repositories:
- name: "Centos 7.2"
product: "Centos 7"
- name: Centos 7.2
product: Centos 7
- include: katello.yml
vars:
name: "Enable RHEL Product"
entity: "repository_set"
name: Enable RHEL Product
entity: repository_set
params:
name: "Red Hat Enterprise Linux 7 Server (RPMs)"
product: "Red Hat Enterprise Linux Server"
organization: "Default Organization"
basearch: "x86_64"
releasever: "7"
name: Red Hat Enterprise Linux 7 Server (RPMs)
product: Red Hat Enterprise Linux Server
organization: Default Organization
basearch: x86_64
releasever: 7
'''
RETURN = '''# '''
@ -441,18 +441,19 @@ class NailGun(object):
return True
def main():
module = AnsibleModule(
argument_spec=dict(
server_url=dict(required=True),
username=dict(required=True, no_log=True),
password=dict(required=True, no_log=True),
entity=dict(required=True, no_log=False),
action=dict(required=False, no_log=False),
verify_ssl=dict(required=False, type='bool', default=False),
params=dict(required=True, no_log=True, type='dict'),
server_url=dict(type='str', required=True),
username=dict(type='str', required=True, no_log=True),
password=dict(type='str', required=True, no_log=True),
entity=dict(type='str', required=True),
action=dict(type='str'),
verify_ssl=dict(type='bool', default=False),
params=dict(type='dict', required=True, no_log=True),
),
supports_check_mode=True
supports_check_mode=True,
)
if not HAS_NAILGUN_PACKAGE:

View File

@ -0,0 +1,205 @@
#!/usr/bin/python
# Copyright: (c) 2016-2017, Hewlett Packard Enterprise Development LP
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: oneview_enclosure_facts
short_description: Retrieve facts about one or more Enclosures
description:
- Retrieve facts about one or more of the Enclosures from OneView.
version_added: "2.5"
requirements:
- hpOneView >= 2.0.1
author:
- Felipe Bulsoni (@fgbulsoni)
- Thiago Miotto (@tmiotto)
- Adriane Cardozo (@adriane-cardozo)
options:
name:
description:
- Enclosure name.
options:
description:
- "List with options to gather additional facts about an Enclosure and related resources.
Options allowed: C(script), C(environmentalConfiguration), and C(utilization). For the option C(utilization),
you can provide specific parameters."
extends_documentation_fragment:
- oneview
- oneview.factsparams
'''
EXAMPLES = '''
- name: Gather facts about all Enclosures
oneview_enclosure_facts:
hostname: 172.16.101.48
username: administrator
password: my_password
api_version: 500
no_log: true
delegate_to: localhost
- debug: var=enclosures
- name: Gather paginated, filtered and sorted facts about Enclosures
oneview_enclosure_facts:
params:
start: 0
count: 3
sort: name:descending
filter: status=OK
hostname: 172.16.101.48
username: administrator
password: my_password
api_version: 500
no_log: true
delegate_to: localhost
- debug: var=enclosures
- name: Gather facts about an Enclosure by name
oneview_enclosure_facts:
name: Enclosure-Name
hostname: 172.16.101.48
username: administrator
password: my_password
api_version: 500
no_log: true
delegate_to: localhost
- debug: var=enclosures
- name: Gather facts about an Enclosure by name with options
oneview_enclosure_facts:
name: Test-Enclosure
options:
- script # optional
- environmentalConfiguration # optional
- utilization # optional
hostname: 172.16.101.48
username: administrator
password: my_password
api_version: 500
no_log: true
delegate_to: localhost
- debug: var=enclosures
- debug: var=enclosure_script
- debug: var=enclosure_environmental_configuration
- debug: var=enclosure_utilization
- name: "Gather facts about an Enclosure with temperature data at a resolution of one sample per day, between two
specified dates"
oneview_enclosure_facts:
name: Test-Enclosure
options:
- utilization: # optional
fields: AmbientTemperature
filter:
- startDate=2016-07-01T14:29:42.000Z
- endDate=2017-07-01T03:29:42.000Z
view: day
refresh: false
hostname: 172.16.101.48
username: administrator
password: my_password
api_version: 500
no_log: true
delegate_to: localhost
- debug: var=enclosures
- debug: var=enclosure_utilization
'''
RETURN = '''
enclosures:
description: Has all the OneView facts about the Enclosures.
returned: Always, but can be null.
type: dict
enclosure_script:
description: Has all the OneView facts about the script of an Enclosure.
returned: When requested, but can be null.
type: string
enclosure_environmental_configuration:
description: Has all the OneView facts about the environmental configuration of an Enclosure.
returned: When requested, but can be null.
type: dict
enclosure_utilization:
description: Has all the OneView facts about the utilization of an Enclosure.
returned: When requested, but can be null.
type: dict
'''
from ansible.module_utils.oneview import OneViewModuleBase
class EnclosureFactsModule(OneViewModuleBase):
argument_spec = dict(name=dict(type='str'), options=dict(type='list'), params=dict(type='dict'))
def __init__(self):
super(EnclosureFactsModule, self).__init__(additional_arg_spec=self.argument_spec)
def execute_module(self):
ansible_facts = {}
if self.module.params['name']:
enclosures = self._get_by_name(self.module.params['name'])
if self.options and enclosures:
ansible_facts = self._gather_optional_facts(self.options, enclosures[0])
else:
enclosures = self.oneview_client.enclosures.get_all(**self.facts_params)
ansible_facts['enclosures'] = enclosures
return dict(changed=False,
ansible_facts=ansible_facts)
def _gather_optional_facts(self, options, enclosure):
enclosure_client = self.oneview_client.enclosures
ansible_facts = {}
if options.get('script'):
ansible_facts['enclosure_script'] = enclosure_client.get_script(enclosure['uri'])
if options.get('environmentalConfiguration'):
env_config = enclosure_client.get_environmental_configuration(enclosure['uri'])
ansible_facts['enclosure_environmental_configuration'] = env_config
if options.get('utilization'):
ansible_facts['enclosure_utilization'] = self._get_utilization(enclosure, options['utilization'])
return ansible_facts
def _get_utilization(self, enclosure, params):
fields = view = refresh = filter = ''
if isinstance(params, dict):
fields = params.get('fields')
view = params.get('view')
refresh = params.get('refresh')
filter = params.get('filter')
return self.oneview_client.enclosures.get_utilization(enclosure['uri'],
fields=fields,
filter=filter,
refresh=refresh,
view=view)
def _get_by_name(self, name):
return self.oneview_client.enclosures.get_by('name', name)
def main():
EnclosureFactsModule().run()
if __name__ == '__main__':
main()

View File

@ -0,0 +1,110 @@
#!/usr/bin/python
# Copyright: (c) 2016-2017, Hewlett Packard Enterprise Development LP
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
ANSIBLE_METADATA = {'metadata_version': '1.1',
'status': ['preview'],
'supported_by': 'community'}
DOCUMENTATION = '''
---
module: oneview_logical_interconnect_group_facts
short_description: Retrieve facts about one or more of the OneView Logical Interconnect Groups
description:
- Retrieve facts about one or more of the Logical Interconnect Groups from OneView
version_added: "2.5"
requirements:
- hpOneView >= 2.0.1
author:
- Felipe Bulsoni (@fgbulsoni)
- Thiago Miotto (@tmiotto)
- Adriane Cardozo (@adriane-cardozo)
options:
name:
description:
- Logical Interconnect Group name.
extends_documentation_fragment:
- oneview
- oneview.factsparams
'''
EXAMPLES = '''
- name: Gather facts about all Logical Interconnect Groups
oneview_logical_interconnect_group_facts:
hostname: 172.16.101.48
username: administrator
password: my_password
api_version: 500
no_log: true
delegate_to: localhost
- debug: var=logical_interconnect_groups
- name: Gather paginated, filtered and sorted facts about Logical Interconnect Groups
oneview_logical_interconnect_group_facts:
params:
start: 0
count: 3
sort: name:descending
filter: name=LIGName
hostname: 172.16.101.48
username: administrator
password: my_password
api_version: 500
no_log: true
delegate_to: localhost
- debug: var=logical_interconnect_groups
- name: Gather facts about a Logical Interconnect Group by name
oneview_logical_interconnect_group_facts:
name: logical lnterconnect group name
hostname: 172.16.101.48
username: administrator
password: my_password
api_version: 500
no_log: true
delegate_to: localhost
- debug: var=logical_interconnect_groups
'''
RETURN = '''
logical_interconnect_groups:
description: Has all the OneView facts about the Logical Interconnect Groups.
returned: Always, but can be null.
type: dict
'''
from ansible.module_utils.oneview import OneViewModuleBase
class LogicalInterconnectGroupFactsModule(OneViewModuleBase):
def __init__(self):
argument_spec = dict(
name=dict(type='str'),
params=dict(type='dict'),
)
super(LogicalInterconnectGroupFactsModule, self).__init__(additional_arg_spec=argument_spec)
def execute_module(self):
if self.module.params.get('name'):
ligs = self.oneview_client.logical_interconnect_groups.get_by('name', self.module.params['name'])
else:
ligs = self.oneview_client.logical_interconnect_groups.get_all(**self.facts_params)
return dict(changed=False, ansible_facts=dict(logical_interconnect_groups=ligs))
def main():
LogicalInterconnectGroupFactsModule().run()
if __name__ == '__main__':
main()

View File

@ -78,6 +78,7 @@ options:
- Path to hg executable to use. If not supplied,
the normal mechanism for resolving binary paths will be used.
notes:
- "This module does not support push capability. See U(https://github.com/ansible/ansible/issues/31156)."
- "If the task seems to be hanging, first verify remote host is in C(known_hosts).
SSH will prompt user to authorize the first contact with a remote host. To avoid this prompt,
one solution is to add the remote host public key in C(/etc/ssh/ssh_known_hosts) before calling

View File

@ -144,7 +144,28 @@ def check_cert_present(module, executable, keystore_path, keystore_pass, alias):
def import_cert_url(module, executable, url, port, keystore_path, keystore_pass, alias):
''' Import certificate from URL into keystore located at keystore_path '''
fetch_cmd = ("%s -printcert -rfc -sslserver %s:%d")%(executable, url, port)
import re
https_proxy = os.getenv("https_proxy")
no_proxy = os.getenv("no_proxy")
proxy_opts = ''
if https_proxy is not None:
(proxy_host, proxy_port) = https_proxy.split(':')
proxy_opts = ("-J-Dhttps.proxyHost=%s -J-Dhttps.proxyPort=%s")%(proxy_host, proxy_port)
if no_proxy is not None:
# For Java's nonProxyHosts property, items are separated by '|',
# and patterns have to start with "*".
non_proxy_hosts = no_proxy.replace(',', '|')
non_proxy_hosts = re.sub(r'(^|\|)\.', r'\1*.', non_proxy_hosts)
# The property name is http.nonProxyHosts, there is no
# separate setting for HTTPS.
proxy_opts += (" -J-Dhttp.nonProxyHosts='%s'")%(non_proxy_hosts)
fetch_cmd = ("%s -printcert -rfc -sslserver %s %s:%d")%(executable, proxy_opts, url, port)
import_cmd = ("%s -importcert -noprompt -keystore '%s' "
"-storepass '%s' -alias '%s'")%(executable, keystore_path,
keystore_pass, alias)

View File

@ -138,45 +138,7 @@ options:
required: False
default: "present"
choices: ["present", "absent"]
tower_host:
description:
- URL to your Tower instance.
required: False
default: null
tower_username:
description:
- Username for your Tower instance.
required: False
default: null
tower_password:
description:
- Password for your Tower instance.
required: False
default: null
tower_verify_ssl:
description:
- Dis/allow insecure connections to Tower. If C(no), SSL certificates will not be validated.
This should only be used on personally controlled sites using self-signed certificates.
required: False
default: True
tower_config_file:
description:
- Path to the Tower config file. See notes.
required: False
default: null
requirements:
- "python >= 2.6"
- "ansible-tower-cli >= 3.0.2"
notes:
- If no I(config_file) is provided we will attempt to use the tower-cli library
defaults to find your Tower host information.
- I(config_file) should contain Tower configuration in the following format
host=hostname
username=username
password=password
extends_documentation_fragment: tower
'''
@ -190,56 +152,52 @@ EXAMPLES = '''
tower_config_file: "~/tower_cli.cfg"
'''
import os
from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI
try:
import os
import tower_cli
import tower_cli.utils.exceptions as exc
from tower_cli.conf import settings
from ansible.module_utils.ansible_tower import tower_auth_config, tower_check_mode
HAS_TOWER_CLI = True
except ImportError:
HAS_TOWER_CLI = False
pass
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(required=True),
user=dict(),
team=dict(),
kind=dict(required=True,
choices=["ssh", "net", "scm", "aws", "rax", "vmware", "satellite6",
"cloudforms", "gce", "azure", "azure_rm", "openstack"]),
host=dict(),
username=dict(),
password=dict(no_log=True),
ssh_key_data=dict(no_log=True),
ssh_key_unlock=dict(no_log=True),
authorize=dict(type='bool', default=False),
authorize_password=dict(no_log=True),
client=dict(),
secret=dict(),
tenant=dict(),
subscription=dict(),
domain=dict(),
become_method=dict(),
become_username=dict(),
become_password=dict(no_log=True),
vault_password=dict(no_log=True),
description=dict(),
organization=dict(required=True),
project=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'),
state=dict(choices=['present', 'absent'], default='present'),
),
supports_check_mode=True
)
argument_spec = tower_argument_spec()
argument_spec.update(dict(
name=dict(required=True),
user=dict(),
team=dict(),
kind=dict(required=True,
choices=["ssh", "net", "scm", "aws", "rax", "vmware", "satellite6",
"cloudforms", "gce", "azure", "azure_rm", "openstack"]),
host=dict(),
username=dict(),
password=dict(no_log=True),
ssh_key_data=dict(no_log=True),
ssh_key_unlock=dict(no_log=True),
authorize=dict(type='bool', default=False),
authorize_password=dict(no_log=True),
client=dict(),
secret=dict(),
tenant=dict(),
subscription=dict(),
domain=dict(),
become_method=dict(),
become_username=dict(),
become_password=dict(no_log=True),
vault_password=dict(no_log=True),
description=dict(),
organization=dict(required=True),
project=dict(),
state=dict(choices=['present', 'absent'], default='present'),
))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
if not HAS_TOWER_CLI:
module.fail_json(msg='ansible-tower-cli required for this module')

View File

@ -98,45 +98,7 @@ options:
required: False
default: "present"
choices: ["present", "absent"]
tower_host:
description:
- URL to your Tower instance.
required: False
default: null
tower_username:
description:
- Username for your Tower instance.
required: False
default: null
tower_password:
description:
- Password for your Tower instance.
required: False
default: null
tower_verify_ssl:
description:
- Dis/allow insecure connections to Tower. If C(no), SSL certificates will not be validated.
This should only be used on personally controlled sites using self-signed certificates.
required: False
default: True
tower_config_file:
description:
- Path to the Tower config file. See notes.
required: False
default: null
requirements:
- "python >= 2.6"
- "ansible-tower-cli >= 3.0.2"
notes:
- If no I(config_file) is provided we will attempt to use the tower-cli library
defaults to find your Tower host information.
- I(config_file) should contain Tower configuration in the following format
host=hostname
username=username
password=password
extends_documentation_fragment: tower
'''
@ -150,48 +112,42 @@ EXAMPLES = '''
tower_config_file: "~/tower_cli.cfg"
'''
import os
from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI
try:
import os
import tower_cli
import tower_cli.utils.exceptions as exc
from tower_cli.conf import settings
from ansible.module_utils.ansible_tower import tower_auth_config, tower_check_mode
HAS_TOWER_CLI = True
except ImportError:
HAS_TOWER_CLI = False
pass
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(required=True),
description=dict(),
inventory=dict(required=True),
variables=dict(),
credential=dict(),
source=dict(choices=["manual", "file", "ec2", "rax", "vmware",
"gce", "azure", "azure_rm", "openstack",
"satellite6", "cloudforms", "custom"], default="manual"),
source_regions=dict(),
source_vars=dict(),
instance_filters=dict(),
group_by=dict(),
source_script=dict(),
overwrite=dict(type='bool', default=False),
overwrite_vars=dict(),
update_on_launch=dict(type='bool', default=False),
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'),
state=dict(choices=['present', 'absent'], default='present'),
),
supports_check_mode=True
)
argument_spec = tower_argument_spec()
argument_spec.update(dict(
name=dict(required=True),
description=dict(),
inventory=dict(required=True),
variables=dict(),
credential=dict(),
source=dict(choices=["manual", "file", "ec2", "rax", "vmware",
"gce", "azure", "azure_rm", "openstack",
"satellite6", "cloudforms", "custom"], default="manual"),
source_regions=dict(),
source_vars=dict(),
instance_filters=dict(),
group_by=dict(),
source_script=dict(),
overwrite=dict(type='bool', default=False),
overwrite_vars=dict(),
update_on_launch=dict(type='bool', default=False),
state=dict(choices=['present', 'absent'], default='present'),
))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
if not HAS_TOWER_CLI:
module.fail_json(msg='ansible-tower-cli required for this module')

View File

@ -50,45 +50,7 @@ options:
required: False
default: "present"
choices: ["present", "absent"]
tower_host:
description:
- URL to your Tower instance.
required: False
default: null
tower_username:
description:
- Username for your Tower instance.
required: False
default: null
tower_password:
description:
- Password for your Tower instance.
required: False
default: null
tower_verify_ssl:
description:
- Dis/allow insecure connections to Tower. If C(no), SSL certificates will not be validated.
This should only be used on personally controlled sites using self-signed certificates.
required: False
default: True
tower_config_file:
description:
- Path to the Tower config file. See notes.
required: False
default: null
requirements:
- "python >= 2.6"
- "ansible-tower-cli >= 3.0.3"
notes:
- If no I(config_file) is provided we will attempt to use the tower-cli library
defaults to find your Tower host information.
- I(config_file) should contain Tower configuration in the following format
host=hostname
username=username
password=password
extends_documentation_fragment: tower
'''
@ -103,36 +65,30 @@ EXAMPLES = '''
'''
import os
from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI
try:
import os
import tower_cli
import tower_cli.utils.exceptions as exc
from tower_cli.conf import settings
from ansible.module_utils.ansible_tower import tower_auth_config, tower_check_mode
HAS_TOWER_CLI = True
except ImportError:
HAS_TOWER_CLI = False
pass
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(required=True),
description=dict(),
inventory=dict(required=True),
enabled=dict(type='bool', default=True),
variables=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'),
state=dict(choices=['present', 'absent'], default='present'),
),
supports_check_mode=True
)
argument_spec = tower_argument_spec()
argument_spec.update(dict(
name=dict(required=True),
description=dict(),
inventory=dict(required=True),
enabled=dict(type='bool', default=True),
variables=dict(),
state=dict(choices=['present', 'absent'], default='present'),
))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
if not HAS_TOWER_CLI:
module.fail_json(msg='ansible-tower-cli required for this module')

View File

@ -47,45 +47,7 @@ options:
required: False
default: "present"
choices: ["present", "absent"]
tower_host:
description:
- URL to your Tower instance.
required: False
default: null
tower_username:
description:
- Username for your Tower instance.
required: False
default: null
tower_password:
description:
- Password for your Tower instance.
required: False
default: null
tower_verify_ssl:
description:
- Dis/allow insecure connections to Tower. If C(no), SSL certificates will not be validated.
This should only be used on personally controlled sites using self-signed certificates.
required: False
default: True
tower_config_file:
description:
- Path to the Tower config file. See notes.
required: False
default: null
requirements:
- "python >= 2.6"
- "ansible-tower-cli >= 3.0.3"
notes:
- If no I(config_file) is provided we will attempt to use the tower-cli library
defaults to find your Tower host information.
- I(config_file) should contain Tower configuration in the following format
host=hostname
username=username
password=password
extends_documentation_fragment: tower
'''
@ -100,34 +62,28 @@ EXAMPLES = '''
'''
from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI
try:
import tower_cli
import tower_cli.utils.exceptions as exc
from tower_cli.conf import settings
from ansible.module_utils.ansible_tower import tower_auth_config, tower_check_mode
HAS_TOWER_CLI = True
except ImportError:
HAS_TOWER_CLI = False
pass
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(required=True),
description=dict(),
organization=dict(required=True),
variables=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'),
state=dict(choices=['present', 'absent'], default='present'),
),
supports_check_mode=True
)
argument_spec = tower_argument_spec()
argument_spec.update(dict(
name=dict(required=True),
description=dict(),
organization=dict(required=True),
variables=dict(),
state=dict(choices=['present', 'absent'], default='present'),
))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
if not HAS_TOWER_CLI:
module.fail_json(msg='ansible-tower-cli required for this module')

View File

@ -56,20 +56,15 @@ status:
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.ansible_tower import tower_auth_config, tower_check_mode, tower_argument_spec, HAS_TOWER_CLI
try:
import tower_cli
import tower_cli.utils.exceptions as exc
from tower_cli.conf import settings
from ansible.module_utils.ansible_tower import (
tower_auth_config,
tower_check_mode,
tower_argument_spec,
)
HAS_TOWER_CLI = True
except ImportError:
HAS_TOWER_CLI = False
pass
def main():

View File

@ -90,20 +90,15 @@ status:
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.ansible_tower import tower_auth_config, tower_check_mode, tower_argument_spec, HAS_TOWER_CLI
try:
import tower_cli
import tower_cli.utils.exceptions as exc
from tower_cli.conf import settings
from ansible.module_utils.ansible_tower import (
tower_auth_config,
tower_check_mode,
tower_argument_spec,
)
HAS_TOWER_CLI = True
except ImportError:
HAS_TOWER_CLI = False
pass
def main():

View File

@ -82,20 +82,15 @@ results:
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.ansible_tower import tower_auth_config, tower_check_mode, tower_argument_spec, HAS_TOWER_CLI
try:
import tower_cli
import tower_cli.utils.exceptions as exc
from tower_cli.conf import settings
from ansible.module_utils.ansible_tower import (
tower_auth_config,
tower_check_mode,
tower_argument_spec,
)
HAS_TOWER_CLI = True
except ImportError:
HAS_TOWER_CLI = False
pass
def main():

View File

@ -137,45 +137,7 @@ options:
required: False
default: "present"
choices: ["present", "absent"]
tower_host:
description:
- URL to your Tower instance.
required: False
default: null
tower_username:
description:
- Username for your Tower instance.
required: False
default: null
tower_password:
description:
- Password for your Tower instance.
required: False
default: null
tower_verify_ssl:
description:
- Dis/allow insecure connections to Tower. If C(no), SSL certificates will not be validated.
This should only be used on personally controlled sites using self-signed certificates.
required: False
default: True
tower_config_file:
description:
- Path to the Tower config file. See notes.
required: False
default: null
requirements:
- "python >= 2.6"
- "ansible-tower-cli >= 3.0.3"
notes:
- If no I(config_file) is provided we will attempt to use the tower-cli library
defaults to find your Tower host information.
- I(config_file) should contain Tower configuration in the following format
host=hostname
username=username
password=password
extends_documentation_fragment: tower
'''
@ -192,16 +154,15 @@ EXAMPLES = '''
tower_config_file: "~/tower_cli.cfg"
'''
from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI
try:
import tower_cli
import tower_cli.utils.exceptions as exc
from tower_cli.conf import settings
from ansible.module_utils.ansible_tower import tower_auth_config, tower_check_mode
HAS_TOWER_CLI = True
except ImportError:
HAS_TOWER_CLI = False
pass
def update_fields(p):
@ -252,40 +213,35 @@ def update_resources(module, p):
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(required=True),
description=dict(),
job_type=dict(choices=['run', 'check', 'scan'], required=True),
inventory=dict(),
project=dict(required=True),
playbook=dict(required=True),
machine_credential=dict(),
cloud_credential=dict(),
network_credential=dict(),
forks=dict(type='int'),
limit=dict(),
verbosity=dict(choices=['verbose', 'debug']),
job_tags=dict(),
skip_tags=dict(),
host_config_key=dict(),
extra_vars_path=dict(type='path', required=False),
ask_extra_vars=dict(type='bool', default=False),
ask_limit=dict(type='bool', default=False),
ask_tags=dict(type='bool', default=False),
ask_job_type=dict(type='bool', default=False),
ask_inventory=dict(type='bool', default=False),
ask_credential=dict(type='bool', default=False),
become_enabled=dict(type='bool', default=False),
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'),
state=dict(choices=['present', 'absent'], default='present'),
),
supports_check_mode=True
)
argument_spec = tower_argument_spec()
argument_spec.update(dict(
name=dict(required=True),
description=dict(),
job_type=dict(choices=['run', 'check', 'scan'], required=True),
inventory=dict(),
project=dict(required=True),
playbook=dict(required=True),
machine_credential=dict(),
cloud_credential=dict(),
network_credential=dict(),
forks=dict(type='int'),
limit=dict(),
verbosity=dict(choices=['verbose', 'debug']),
job_tags=dict(),
skip_tags=dict(),
host_config_key=dict(),
extra_vars_path=dict(type='path', required=False),
ask_extra_vars=dict(type='bool', default=False),
ask_limit=dict(type='bool', default=False),
ask_tags=dict(type='bool', default=False),
ask_job_type=dict(type='bool', default=False),
ask_inventory=dict(type='bool', default=False),
ask_credential=dict(type='bool', default=False),
become_enabled=dict(type='bool', default=False),
state=dict(choices=['present', 'absent'], default='present'),
))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
if not HAS_TOWER_CLI:
module.fail_json(msg='ansible-tower-cli required for this module')

View File

@ -82,27 +82,18 @@ status:
'''
from ansible.module_utils.ansible_tower import tower_auth_config, tower_check_mode, tower_argument_spec, HAS_TOWER_CLI
from ansible.module_utils.basic import AnsibleModule
from ansible.module_utils.six.moves import cStringIO as StringIO
try:
from cStringIO import StringIO
except ImportError:
from StringIO import StringIO
try:
import tower_cli
import tower_cli.utils.exceptions as exc
from tower_cli.conf import settings
from ansible.module_utils.ansible_tower import (
tower_auth_config,
tower_check_mode,
tower_argument_spec,
)
HAS_TOWER_CLI = True
except ImportError:
HAS_TOWER_CLI = False
pass
def main():

View File

@ -39,45 +39,7 @@ options:
required: False
default: "present"
choices: ["present", "absent"]
tower_host:
description:
- URL to your Tower instance.
required: False
default: null
tower_username:
description:
- Username for your Tower instance.
required: False
default: null
tower_password:
description:
- Password for your Tower instance.
required: False
default: null
tower_verify_ssl:
description:
- Dis/allow insecure connections to Tower. If C(no), SSL certificates will not be validated.
This should only be used on personally controlled sites using self-signed certificates.
required: False
default: True
tower_config_file:
description:
- Path to the Tower config file. See notes.
required: False
default: null
requirements:
- "python >= 2.6"
- "ansible-tower-cli >= 3.0.3"
notes:
- If no I(config_file) is provided we will attempt to use the tower-cli library
defaults to find your Tower host information.
- I(config_file) should contain Tower configuration in the following format
host=hostname
username=username
password=password
extends_documentation_fragment: tower
'''
@ -90,32 +52,26 @@ EXAMPLES = '''
tower_config_file: "~/tower_cli.cfg"
'''
from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI
try:
import tower_cli
import tower_cli.utils.exceptions as exc
from tower_cli.conf import settings
from ansible.module_utils.ansible_tower import tower_auth_config, tower_check_mode
HAS_TOWER_CLI = True
except ImportError:
HAS_TOWER_CLI = False
pass
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(required=True),
organization=dict(required=True),
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'),
state=dict(choices=['present', 'absent'], default='present'),
),
supports_check_mode=True
)
argument_spec = tower_argument_spec()
argument_spec.update(dict(
name=dict(required=True),
organization=dict(required=True),
state=dict(choices=['present', 'absent'], default='present'),
))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
if not HAS_TOWER_CLI:
module.fail_json(msg='ansible-tower-cli required for this module')

View File

@ -38,45 +38,7 @@ options:
required: False
default: "present"
choices: ["present", "absent"]
tower_host:
description:
- URL to your Tower instance.
required: False
default: null
tower_username:
description:
- Username for your Tower instance.
required: False
default: null
tower_password:
description:
- Password for your Tower instance.
required: False
default: null
tower_verify_ssl:
description:
- Dis/allow insecure connections to Tower. If C(no), SSL certificates will not be validated.
This should only be used on personally controlled sites using self-signed certificates.
required: False
default: True
tower_config_file:
description:
- Path to the Tower config file. See notes.
required: False
default: null
requirements:
- "python >= 2.6"
- "ansible-tower-cli >= 3.0.3"
notes:
- If no I(tower_config_file) is provided we will attempt to use the tower-cli library
defaults to find your Tower host information.
- I(tower_config_file) should contain Tower configuration in the following format
host=hostname
username=username
password=password
extends_documentation_fragment: tower
'''
@ -89,32 +51,26 @@ EXAMPLES = '''
tower_config_file: "~/tower_cli.cfg"
'''
from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI
try:
import tower_cli
import tower_cli.utils.exceptions as exc
from tower_cli.conf import settings
from ansible.module_utils.ansible_tower import tower_auth_config, tower_check_mode
HAS_TOWER_CLI = True
except ImportError:
HAS_TOWER_CLI = False
pass
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(required=True),
description=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'),
state=dict(choices=['present', 'absent'], default='present'),
),
supports_check_mode=True
)
argument_spec = tower_argument_spec()
argument_spec.update(dict(
name=dict(required=True),
description=dict(),
state=dict(choices=['present', 'absent'], default='present'),
))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
if not HAS_TOWER_CLI:
module.fail_json(msg='ansible-tower-cli required for this module')

View File

@ -85,45 +85,7 @@ options:
required: False
default: "present"
choices: ["present", "absent"]
tower_host:
description:
- URL to your Tower instance.
required: False
default: null
tower_username:
description:
- Username for your Tower instance.
required: False
default: null
tower_password:
description:
- Password for your Tower instance.
required: False
default: null
tower_verify_ssl:
description:
- Dis/allow insecure connections to Tower. If C(no), SSL certificates will not be validated.
This should only be used on personally controlled sites using self-signed certificates.
required: False
default: True
tower_config_file:
description:
- Path to the Tower config file. See notes.
required: False
default: null
requirements:
- "python >= 2.6"
- "ansible-tower-cli >= 3.0.3"
notes:
- If no I(config_file) is provided we will attempt to use the tower-cli library
defaults to find your Tower host information.
- I(config_file) should contain Tower configuration in the following format
host=hostname
username=username
password=password
extends_documentation_fragment: tower
'''
@ -137,42 +99,36 @@ EXAMPLES = '''
tower_config_file: "~/tower_cli.cfg"
'''
from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI
try:
import tower_cli
import tower_cli.utils.exceptions as exc
from tower_cli.conf import settings
from ansible.module_utils.ansible_tower import tower_auth_config, tower_check_mode
HAS_TOWER_CLI = True
except ImportError:
HAS_TOWER_CLI = False
pass
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(),
description=dict(),
organization=dict(),
scm_type=dict(choices=['manual', 'git', 'hg', 'svn'], default='manual'),
scm_url=dict(),
scm_branch=dict(),
scm_credential=dict(),
scm_clean=dict(type='bool', default=False),
scm_delete_on_update=dict(type='bool', default=False),
scm_update_on_launch=dict(type='bool', default=False),
local_path=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'),
argument_spec = tower_argument_spec()
argument_spec.update(dict(
name=dict(),
description=dict(),
organization=dict(),
scm_type=dict(choices=['manual', 'git', 'hg', 'svn'], default='manual'),
scm_url=dict(),
scm_branch=dict(),
scm_credential=dict(),
scm_clean=dict(type='bool', default=False),
scm_delete_on_update=dict(type='bool', default=False),
scm_update_on_launch=dict(type='bool', default=False),
local_path=dict(),
state=dict(choices=['present', 'absent'], default='present'),
),
supports_check_mode=True
)
state=dict(choices=['present', 'absent'], default='present'),
))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
if not HAS_TOWER_CLI:
module.fail_json(msg='ansible-tower-cli required for this module')

View File

@ -74,45 +74,7 @@ options:
required: False
default: "present"
choices: ["present", "absent"]
tower_host:
description:
- URL to your Tower instance.
required: False
default: null
tower_username:
description:
- Username for your Tower instance.
required: False
default: null
tower_password:
description:
- Password for your Tower instance.
required: False
default: null
tower_verify_ssl:
description:
- Dis/allow insecure connections to Tower. If C(no), SSL certificates will not be validated.
This should only be used on personally controlled sites using self-signed certificates.
required: False
default: True
tower_config_file:
description:
- Path to the Tower config file. See notes.
required: False
default: null
requirements:
- "python >= 2.6"
- "ansible-tower-cli >= 3.0.3"
notes:
- If no I(config_file) is provided we will attempt to use the tower-cli library
defaults to find your Tower host information.
- I(config_file) should contain Tower configuration in the following format
host=hostname
username=username
password=password
extends_documentation_fragment: tower
'''
@ -126,16 +88,15 @@ EXAMPLES = '''
tower_config_file: "~/tower_cli.cfg"
'''
from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI
try:
import tower_cli
import tower_cli.utils.exceptions as exc
from tower_cli.conf import settings
from ansible.module_utils.ansible_tower import tower_auth_config, tower_check_mode
HAS_TOWER_CLI = True
except ImportError:
HAS_TOWER_CLI = False
pass
def update_resources(module, p):
@ -165,26 +126,22 @@ def update_resources(module, p):
def main():
module = AnsibleModule(
argument_spec=dict(
user=dict(),
team=dict(),
role=dict(choices=["admin", "read", "member", "execute", "adhoc", "update", "use", "auditor"]),
target_team=dict(),
inventory=dict(),
job_template=dict(),
credential=dict(),
organization=dict(),
project=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'),
state=dict(choices=['present', 'absent'], default='present'),
),
supports_check_mode=True
)
argument_spec = tower_argument_spec()
argument_spec.update(dict(
user=dict(),
team=dict(),
role=dict(choices=["admin", "read", "member", "execute", "adhoc", "update", "use", "auditor"]),
target_team=dict(),
inventory=dict(),
job_template=dict(),
credential=dict(),
organization=dict(),
project=dict(),
state=dict(choices=['present', 'absent'], default='present'),
))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
if not HAS_TOWER_CLI:
module.fail_json(msg='ansible-tower-cli required for this module')

View File

@ -39,45 +39,7 @@ options:
required: False
default: "present"
choices: ["present", "absent"]
tower_host:
description:
- URL to your Tower instance.
required: False
default: null
tower_username:
description:
- Username for your Tower instance.
required: False
default: null
tower_password:
description:
- Password for your Tower instance.
required: False
default: null
tower_verify_ssl:
description:
- Dis/allow insecure connections to Tower. If C(no), SSL certificates will not be validated.
This should only be used on personally controlled sites using self-signed certificates.
required: False
default: True
tower_config_file:
description:
- Path to the Tower config file. See notes.
required: False
default: null
requirements:
- "python >= 2.6"
- "ansible-tower-cli >= 3.0.3"
notes:
- If no I(config_file) is provided we will attempt to use the tower-cli library
defaults to find your Tower host information.
- I(config_file) should contain Tower configuration in the following format
host=hostname
username=username
password=password
extends_documentation_fragment: tower
'''
@ -91,33 +53,28 @@ EXAMPLES = '''
tower_config_file: "~/tower_cli.cfg"
'''
from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI
try:
import tower_cli
import tower_cli.utils.exceptions as exc
from tower_cli.conf import settings
from ansible.module_utils.ansible_tower import tower_auth_config, tower_check_mode
HAS_TOWER_CLI = True
except ImportError:
HAS_TOWER_CLI = False
pass
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(required=True),
description=dict(),
organization=dict(required=True),
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'),
state=dict(choices=['present', 'absent'], default='present'),
),
supports_check_mode=True
)
argument_spec = tower_argument_spec()
argument_spec.update(dict(
name=dict(required=True),
description=dict(),
organization=dict(required=True),
state=dict(choices=['present', 'absent'], default='present'),
))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
if not HAS_TOWER_CLI:
module.fail_json(msg='ansible-tower-cli required for this module')

View File

@ -62,45 +62,7 @@ options:
required: False
default: "present"
choices: ["present", "absent"]
tower_host:
description:
- URL to your Tower instance.
required: False
default: null
tower_username:
description:
- Username for your Tower instance.
required: False
default: null
tower_password:
description:
- Password for your Tower instance.
required: False
default: null
tower_verify_ssl:
description:
- Dis/allow insecure connections to Tower. If C(no), SSL certificates will not be validated.
This should only be used on personally controlled sites using self-signed certificates.
required: False
default: True
tower_config_file:
description:
- Path to the Tower config file. See notes.
required: False
default: null
requirements:
- "python >= 2.6"
- "ansible-tower-cli >= 3.0.3"
notes:
- If no I(config_file) is provided we will attempt to use the tower-cli library
defaults to find your Tower host information.
- I(config_file) should contain Tower configuration in the following format
host=hostname
username=username
password=password
extends_documentation_fragment: tower
'''
@ -116,37 +78,31 @@ EXAMPLES = '''
tower_config_file: "~/tower_cli.cfg"
'''
from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI
try:
import tower_cli
import tower_cli.utils.exceptions as exc
from tower_cli.conf import settings
from ansible.module_utils.ansible_tower import tower_auth_config, tower_check_mode
HAS_TOWER_CLI = True
except ImportError:
HAS_TOWER_CLI = False
pass
def main():
module = AnsibleModule(
argument_spec=dict(
username=dict(required=True),
first_name=dict(),
last_name=dict(),
password=dict(no_log=True),
email=dict(required=True),
superuser=dict(type='bool', default=False),
auditor=dict(type='bool', default=False),
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'),
state=dict(choices=['present', 'absent'], default='present'),
),
supports_check_mode=True
)
argument_spec = tower_argument_spec()
argument_spec.update(dict(
username=dict(required=True),
first_name=dict(),
last_name=dict(),
password=dict(no_log=True),
email=dict(required=True),
superuser=dict(type='bool', default=False),
auditor=dict(type='bool', default=False),
state=dict(choices=['present', 'absent'], default='present'),
))
module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)
if not HAS_TOWER_CLI:
module.fail_json(msg='ansible-tower-cli required for this module')

View File

@ -1,71 +1,62 @@
#!powershell
# This file is part of Ansible
#
# Copyright 2015, Peter Mounce <public@neverrunwithscissors.com>
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
# Copyright (c) 2017 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
$ErrorActionPreference = "Stop"
#Requires -Module Ansible.ModuleUtils.Legacy.psm1
#Requires -Module Ansible.ModuleUtils.CommandUtil.psm1
# WANT_JSON
# POWERSHELL_COMMON
$ErrorActionPreference = 'Stop'
$params = Parse-Args $args;
$params = Parse-Args $args -supports_check_mode $true
$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false
$result = @{
changed = $false
}
function Invoke-NGen
{
[CmdletBinding()]
Function Invoke-Ngen($architecture="") {
$cmd = "$($env:windir)\Microsoft.NET\Framework$($architecture)\v4.0.30319\ngen.exe"
param
(
[Parameter(Mandatory=$false, Position=0)] [string] $arity = ""
)
if ($arity -eq $null)
{
$arity = ""
}
$cmd = "$($env:windir)\microsoft.net\framework$($arity)\v4.0.30319\ngen.exe"
if (test-path $cmd)
{
$update = Invoke-Expression "$cmd update /force";
$(result.dotnet_ngen$($arity)_update_exit_code) = $lastexitcode
$(result.dotnet_ngen$($arity)_update_output) = $update
$eqi = Invoke-Expression "$cmd executequeueditems";
$(result.dotnet_ngen$($arity)_eqi_exit_code) = $lastexitcode
$(result.dotnet_ngen$($arity)_eqi_output) = $eqi
if (Test-Path -Path $cmd) {
$arguments = "update /force"
if ($check_mode) {
$ngen_result = @{
rc = 0
stdout = "check mode output for $cmd $arguments"
}
} else {
try {
$ngen_result = Run-Command -command "$cmd $arguments"
} catch {
Fail-Json -obj $result -message "failed to execute '$cmd $arguments': $($_.Exception.Message)"
}
}
$result."dotnet_ngen$($architecture)_update_exit_code" = $ngen_result.rc
$result."dotnet_ngen$($architecture)_update_output" = $ngen_result.stdout
$arguments = "executeQueuedItems"
if ($check_mode) {
$executed_queued_items = @{
rc = 0
stdout = "check mode output for $cmd $arguments"
}
} else {
try {
$executed_queued_items = Run-Command -command "$cmd $arguments"
} catch {
Fail-Json -obj $result -message "failed to execute '$cmd $arguments': $($_.Exception.Message)"
}
}
$result."dotnet_ngen$($architecture)_eqi_exit_code" = $executed_queued_items.rc
$result."dotnet_ngen$($architecture)_eqi_output" = $executed_queued_items.stdout
$result.changed = $true
}
else
{
Write-Host "Not found: $cmd"
}
}
Try
{
Invoke-NGen
Invoke-NGen -arity "64"
Invoke-Ngen
Invoke-Ngen -architecture "64"
Exit-Json $result;
}
Catch
{
Fail-Json $result $_.Exception.Message
}
Exit-Json -obj $result

View File

@ -45,6 +45,57 @@ options: {}
'''
EXAMPLES = r'''
# Run ngen tasks
- name: run ngen tasks
win_dotnet_ngen:
'''
RETURN = r'''
dotnet_ngen_update_exit_code:
description: The exit code after running the 32-bit ngen.exe update /force
command.
returned: 32-bit ngen executable exists
type: int
sample: 0
dotnet_ngen_update_output:
description: The stdout after running the 32-bit ngen.exe update /force
command.
returned: 32-bit ngen executable exists
type: str
sample: sample output
dotnet_ngen_eqi_exit_code:
description: The exit code after running the 32-bit ngen.exe
executeQueuedItems command.
returned: 32-bit ngen executable exists
type: int
sample: 0
dotnet_ngen_eqi_output:
description: The stdout after running the 32-bit ngen.exe executeQueuedItems
command.
returned: 32-bit ngen executable exists
type: str
sample: sample output
dotnet_ngen64_update_exit_code:
description: The exit code after running the 64-bit ngen.exe update /force
command.
returned: 64-bit ngen executable exists
type: int
sample: 0
dotnet_ngen64_update_output:
description: The stdout after running the 64-bit ngen.exe update /force
command.
returned: 64-bit ngen executable exists
type: str
sample: sample output
dotnet_ngen64_eqi_exit_code:
description: The exit code after running the 64-bit ngen.exe
executeQueuedItems command.
returned: 64-bit ngen executable exists
type: int
sample: 0
dotnet_ngen64_eqi_output:
description: The stdout after running the 64-bit ngen.exe executeQueuedItems
command.
returned: 64-bit ngen executable exists
type: str
sample: sample output
'''

View File

@ -36,6 +36,10 @@ $result = @{
wait = $wait
}
if ($msg.Length -gt 255) {
Fail-Json -obj $result -message "msg length must be less than 256 characters, current length: $($msg.Length)"
}
$msg_args = @($to, "/TIME:$display_seconds")
if ($wait) {

View File

@ -51,6 +51,7 @@ options:
msg:
description:
- The text of the message to be displayed.
- The message must be less than 256 characters.
default: Hello world!
author:
- Jon Hawkesworth (@jhawkesworth)

View File

@ -109,15 +109,18 @@ class ActionModule(ActionBase):
if self.source_dir:
self._set_dir_defaults()
self._set_root_dir()
if path.exists(self.source_dir):
if not path.exists(self.source_dir):
failed = True
err_msg = ('{0} directory does not exist'.format(self.source_dir))
elif not path.isdir(self.source_dir):
failed = True
err_msg = ('{0} is not a directory'.format(self.source_dir))
else:
for root_dir, filenames in self._traverse_dir_depth():
failed, err_msg, updated_results = (self._load_files_in_dir(root_dir, filenames))
if failed:
break
results.update(updated_results)
else:
failed = True
err_msg = ('{0} directory does not exist'.format(self.source_dir))
else:
try:
self.source_file = self._find_needle('vars', self.source_file)

View File

@ -116,7 +116,7 @@ class CacheModule(BaseCacheModule):
return (self._db.zrank(self._keys_set, key) is not None)
def delete(self, key):
del self.cache[key]
del self._cache[key]
self._db.delete(self._make_key(key))
self._db.zrem(self._keys_set, key)

View File

@ -116,11 +116,18 @@ DOCUMENTATION = '''
- However this conflicts with privilege escalation (become).
For example, when using sudo operations you must first disable 'requiretty' in the sudoers file for the target hosts,
which is why this feature is disabled by default.
env: [{name: ANSIBLE_SSH_PIPELINING}]
env:
- name: ANSIBLE_PIPELINING
#- name: ANSIBLE_SSH_PIPELINING
ini:
- {key: pipelining, section: ssh_connection}
- section: defaults
key: pipelining
#- section: ssh_connection
# key: pipelining
type: boolean
vars: [{name: ansible_ssh_pipelining}]
vars:
- name: ansible_pipelining
- name: ansible_ssh_pipelining
private_key_file:
description:
- Path to private key file to use for authentication

View File

@ -24,6 +24,7 @@ import threading
import time
from collections import deque
from multiprocessing import Lock
from jinja2.exceptions import UndefinedError
from ansible import constants as C
@ -31,14 +32,13 @@ from ansible.errors import AnsibleError, AnsibleParserError, AnsibleUndefinedVar
from ansible.executor import action_write_locks
from ansible.executor.task_result import TaskResult
from ansible.inventory.host import Host
from ansible.module_utils.six.moves import queue as Queue
from ansible.module_utils.six import iteritems, string_types
from ansible.module_utils._text import to_text
from ansible.playbook.helpers import load_list_of_blocks
from ansible.playbook.included_file import IncludedFile
from ansible.playbook.task_include import TaskInclude
from ansible.playbook.role_include import IncludeRole
from ansible.plugins.loader import action_loader, connection_loader, filter_loader, lookup_loader, module_loader, test_loader
from ansible.plugins.loader import action_loader, connection_loader
from ansible.template import Templar
from ansible.utils.vars import combine_vars
from ansible.vars.manager import strip_internal_keys
@ -57,33 +57,31 @@ class StrategyBase:
'''
This is the base class for strategy plugins, which contains some common
code useful to all strategies like running handlers, cleanup actions, etc.
code useful to all strategies like running handlers, etc.
'''
def __init__(self, tqm):
self._tqm = tqm
self._inventory = tqm.get_inventory()
self._workers = tqm._workers
self._notified_handlers = tqm._notified_handlers
self._tqm = tqm
self._inventory = tqm.get_inventory()
self._workers = tqm.get_workers()
self._notified_handlers = tqm._notified_handlers
self._listening_handlers = tqm._listening_handlers
self._variable_manager = tqm.get_variable_manager()
self._loader = tqm.get_loader()
self._step = getattr(tqm._options, 'step', False)
self._diff = getattr(tqm._options, 'diff', False)
self._variable_manager = tqm.get_variable_manager()
self._loader = tqm.get_loader()
self._step = getattr(tqm._options, 'step', False)
self._diff = getattr(tqm._options, 'diff', False)
# Backwards compat: self._display isn't really needed, just import the global display and use that.
self._display = display
# internal counters
self._pending_results = 0
self._cur_worker = 0
# this dictionary is used to keep track of hosts that have
# outstanding tasks still in queue
self._blocked_hosts = dict()
def cleanup(self):
self._tqm.terminate()
self._results_lock = threading.Condition(threading.Lock())
def run(self, iterator, play_context, result=0):
# execute one more pass through the iterator without peeking, to
@ -154,8 +152,10 @@ class StrategyBase:
display.debug('Creating lock for %s' % task.action)
action_write_locks.action_write_locks[task.action] = threading.Lock()
self._tqm.put_job((host, task, play_context, task_vars))
self._pending_results += 1
if self._tqm.put_job((host, task, play_context, task_vars)):
self._pending_results += 1
else:
raise AnsibleError('Could not put the job')
display.debug("exiting _queue_task() for %s/%s" % (host.name, task.action))
@ -252,16 +252,14 @@ class StrategyBase:
break
# get the original host and task. We then assign them to the TaskResult for use in callbacks/etc.
#original_host = get_original_host(task_result._host)
#found_task = iterator.get_original_task(original_host, task_result._task)
#original_task = found_task.copy(exclude_parent=True, exclude_tasks=True)
#original_task._parent = found_task._parent
#original_task.from_attrs(task_result._task_fields)
original_host = get_original_host(task_result._host)
found_task = iterator.get_original_task(original_host, task_result._task)
original_task = found_task.copy(exclude_parent=True, exclude_tasks=True)
original_task._parent = found_task._parent
original_task.from_attrs(task_result._task_fields)
#task_result._host = original_host
#task_result._task = original_task
original_host = task_result._host
original_task = task_result._task
task_result._host = original_host
task_result._task = original_task
# get the correct loop var for use later
if original_task.loop_control:
@ -506,9 +504,7 @@ class StrategyBase:
results = self._process_pending_results(iterator)
ret_results.extend(results)
if self._pending_results > 0:
#time.sleep(C.DEFAULT_INTERNAL_POLL_INTERVAL)
self._tqm._res_ready.wait()
self._tqm._res_ready.clear()
time.sleep(C.DEFAULT_INTERNAL_POLL_INTERVAL)
display.debug("no more pending results, returning what we have")

View File

@ -51,7 +51,6 @@ options:
requirements:
- "python >= 2.6"
- "ansible-tower-cli >= 3.0.2"
notes:

View File

@ -24,7 +24,7 @@ optdepends=('python2-pyasn1: needed for accelerated mode'
conflicts=('ansible')
provides=('ansible')
backup=('etc/ansible/ansible.cfg')
source=($pkgname::git://github.com/ansible/ansible.git)
source=($pkgname::git+https://github.com/ansible/ansible.git)
md5sums=('SKIP')
pkgver() {

View File

@ -7,7 +7,7 @@ __Note__: You must run this target as root or set `PBUILDER_BIN='sudo pbuilder'`
```
apt-get install asciidoc cdbs debootstrap devscripts make pbuilder python-setuptools
git clone git://github.com/ansible/ansible.git
git clone https://github.com/ansible/ansible.git
cd ansible
git submodule update --init
DEB_DIST='xenial trusty precise' make deb
@ -16,7 +16,7 @@ DEB_DIST='xenial trusty precise' make deb
Building in Docker:
```
git clone git://github.com/ansible/ansible.git
git clone https://github.com/ansible/ansible.git
cd ansible
git submodule update --init
docker build -t ansible-deb-builder -f packaging/debian/Dockerfile .

View File

@ -23,6 +23,8 @@ echo "This is a test file for edit2" > "${TEST_FILE_EDIT2}"
FORMAT_1_1_HEADER="\$ANSIBLE_VAULT;1.1;AES256"
FORMAT_1_2_HEADER="\$ANSIBLE_VAULT;1.2;AES256"
VAULT_PASSWORD_FILE=vault-password
# old format
ansible-vault view "$@" --vault-password-file vault-password-ansible format_1_0_AES.yml
@ -202,9 +204,16 @@ ansible-vault view "$@" --vault-id "tmp_new_password@${NEW_VAULT_PASSWORD}" --va
ansible-vault decrypt "$@" --vault-password-file "${NEW_VAULT_PASSWORD}" "${TEST_FILE}"
# reading/writing to/from stdin/stdin (See https://github.com/ansible/ansible/issues/23567)
ansible-vault encrypt "$@" --vault-password-file "${NEW_VAULT_PASSWORD}" --output="${TEST_FILE_OUTPUT}" < "${TEST_FILE}"
ansible-vault view "$@" --vault-password-file "${NEW_VAULT_PASSWORD}" - < "${TEST_FILE_OUTPUT}"
ansible-vault decrypt "$@" --vault-password-file "${NEW_VAULT_PASSWORD}" --output=- < "${TEST_FILE_OUTPUT}"
ansible-vault encrypt "$@" --vault-password-file "${VAULT_PASSWORD_FILE}" --output="${TEST_FILE_OUTPUT}" < "${TEST_FILE}"
OUTPUT=$(ansible-vault decrypt "$@" --vault-password-file "${VAULT_PASSWORD_FILE}" --output=- < "${TEST_FILE_OUTPUT}")
echo "${OUTPUT}" | grep 'This is a test file'
OUTPUT_DASH=$(ansible-vault decrypt "$@" --vault-password-file "${VAULT_PASSWORD_FILE}" --output=- "${TEST_FILE_OUTPUT}")
echo "${OUTPUT_DASH}" | grep 'This is a test file'
OUTPUT_DASH_SPACE=$(ansible-vault decrypt "$@" --vault-password-file "${VAULT_PASSWORD_FILE}" --output - "${TEST_FILE_OUTPUT}")
echo "${OUTPUT_DASH_SPACE}" | grep 'This is a test file'
# test using an empty vault password file
ansible-vault view "$@" --vault-password-file empty-password format_1_1_AES256.yml && :

View File

@ -1,3 +1,2 @@
posix/ci/cloud/group1/vcenter
cloud/vcenter
destructive

View File

@ -0,0 +1 @@
windows/ci/group1

View File

@ -0,0 +1,20 @@
# this only tests check mode as the full run can take several minutes to
# complete, this way we at least verify the script is parsable
---
- name: run in check mode
win_dotnet_ngen:
register: result_check
check_mode: yes
- name: assert run in check mode
assert:
that:
- result_check|changed
- result_check.dotnet_ngen_update_exit_code == 0
- result_check.dotnet_ngen_update_output == "check mode output for C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\ngen.exe update /force"
- result_check.dotnet_ngen_eqi_exit_code == 0
- result_check.dotnet_ngen_eqi_output == "check mode output for C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\ngen.exe executeQueuedItems"
- result_check.dotnet_ngen64_update_exit_code == 0
- result_check.dotnet_ngen64_update_output == "check mode output for C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\ngen.exe update /force"
- result_check.dotnet_ngen64_eqi_exit_code == 0
- result_check.dotnet_ngen64_eqi_output == "check mode output for C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\ngen.exe executeQueuedItems"

View File

@ -25,3 +25,9 @@
- not msg_wait_result|failed
- msg_wait_result|changed
- msg_wait_result.runtime_seconds > 5
- name: fail to send a message > 255 characters
win_msg:
msg: "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456"
register: fail_too_long
failed_when: "fail_too_long.msg != 'msg length must be less than 256 characters, current length: 256'"

View File

@ -58,7 +58,7 @@ $(CREDENTIALS_FILE):
@exit 1
amazon: $(CREDENTIALS_FILE)
ANSIBLE_HOST_KEY_CHECKING=False ANSIBLE_SSH_PIPELINING=no BOTO_CONFIG=/dev/null ansible-playbook amazon.yml -i $(INVENTORY) -e @$(VARS_FILE) $(CREDENTIALS_ARG) -e "resource_prefix=$(CLOUD_RESOURCE_PREFIX)" -v $(TEST_FLAGS) ; \
ANSIBLE_HOST_KEY_CHECKING=False ANSIBLE_PIPELINING=no BOTO_CONFIG=/dev/null ansible-playbook amazon.yml -i $(INVENTORY) -e @$(VARS_FILE) $(CREDENTIALS_ARG) -e "resource_prefix=$(CLOUD_RESOURCE_PREFIX)" -v $(TEST_FLAGS) ; \
RC=$$? ; \
CLOUD_RESOURCE_PREFIX="$(CLOUD_RESOURCE_PREFIX)" make amazon_cleanup ; \
exit $$RC;

View File

@ -52,7 +52,8 @@ class CsCloudProvider(CloudProvider):
"""
super(CsCloudProvider, self).__init__(args, config_extension='.ini')
self.image = 'ansible/ansible:cloudstack-simulator'
# The simulator must be pinned to a specific version to guarantee CI passes with the version used.
self.image = 'ansible/ansible:cloudstack-simulator@sha256:885aedb7f34ce7114eaa383a2541ede93c4f8cb543c05edf90b694def67b1a6a'
self.container_name = ''
self.endpoint = ''
self.host = ''

View File

@ -39,7 +39,8 @@ class VcenterProvider(CloudProvider):
"""
super(VcenterProvider, self).__init__(args, config_extension='.ini')
self.image = 'ansible/ansible:vcenter-simulator'
# The simulator must be pinned to a specific version to guarantee CI passes with the version used.
self.image = 'ansible/ansible:vcenter-simulator@sha256:1a92e84f477ae4c45f9070a5419a0fc2b46abaecdb5bc396826741bca65ce028'
self.container_name = ''
def filter(self, targets, exclude):

View File

@ -1,4 +1,3 @@
lib/ansible/module_utils/ansible_tower.py
lib/ansible/modules/cloud/amazon/cloudtrail.py
lib/ansible/modules/cloud/amazon/ec2_vpc_igw.py
lib/ansible/modules/cloud/amazon/ec2_vpc_route_table.py
@ -56,4 +55,3 @@ lib/ansible/modules/network/lenovo/cnos_vlag.py
lib/ansible/modules/network/lenovo/cnos_vlan.py
lib/ansible/modules/network/nxos/nxos_file_copy.py
lib/ansible/modules/packaging/language/maven_artifact.py
lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py

View File

@ -344,7 +344,6 @@ lib/ansible/modules/packaging/language/cpanm.py
lib/ansible/modules/packaging/language/gem.py
lib/ansible/modules/packaging/language/maven_artifact.py
lib/ansible/modules/packaging/language/pear.py
lib/ansible/modules/packaging/language/pip.py
lib/ansible/modules/packaging/os/apk.py
lib/ansible/modules/packaging/os/apt.py
lib/ansible/modules/packaging/os/apt_key.py
@ -362,7 +361,6 @@ lib/ansible/modules/packaging/os/pkgng.py
lib/ansible/modules/packaging/os/pkgutil.py
lib/ansible/modules/packaging/os/portage.py
lib/ansible/modules/packaging/os/portinstall.py
lib/ansible/modules/packaging/os/rhn_channel.py
lib/ansible/modules/packaging/os/rpm_key.py
lib/ansible/modules/packaging/os/sorcery.py
lib/ansible/modules/packaging/os/svr4pkg.py
@ -371,8 +369,6 @@ lib/ansible/modules/packaging/os/urpmi.py
lib/ansible/modules/packaging/os/yum.py
lib/ansible/modules/packaging/os/zypper.py
lib/ansible/modules/packaging/os/zypper_repository.py
lib/ansible/modules/remote_management/foreman/foreman.py
lib/ansible/modules/remote_management/foreman/katello.py
lib/ansible/modules/remote_management/stacki/stacki_host.py
lib/ansible/modules/source_control/bzr.py
lib/ansible/modules/source_control/hg.py

View File

@ -0,0 +1,134 @@
# Copyright (c) 2016-2017 Hewlett Packard Enterprise Development LP
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from ansible.compat.tests import unittest
from oneview_module_loader import OneViewModuleBase
from ansible.modules.remote_management.oneview.oneview_enclosure_facts import EnclosureFactsModule
from hpe_test_utils import FactsParamsTestCase
ERROR_MSG = 'Fake message error'
PARAMS_GET_ALL = dict(
config='config.json',
name=None
)
PARAMS_GET_BY_NAME = dict(
config='config.json',
name="Test-Enclosure",
options=[]
)
PARAMS_GET_BY_NAME_WITH_OPTIONS = dict(
config='config.json',
name="Test-Enclosure",
options=['utilization', 'environmentalConfiguration', 'script']
)
PARAMS_GET_UTILIZATION_WITH_PARAMS = dict(
config='config.json',
name="Test-Enclosure",
options=[dict(utilization=dict(fields='AveragePower',
filter=['startDate=2016-06-30T03:29:42.000Z',
'endDate=2016-07-01T03:29:42.000Z'],
view='day',
refresh=True))]
)
PRESENT_ENCLOSURES = [{
"name": "Test-Enclosure",
"uri": "/rest/enclosures/c6bf9af9-48e7-4236-b08a-77684dc258a5"
}]
ENCLOSURE_SCRIPT = '# script content'
ENCLOSURE_UTILIZATION = {
"isFresh": "True"
}
ENCLOSURE_ENVIRONMENTAL_CONFIG = {
"calibratedMaxPower": "2500"
}
class EnclosureFactsSpec(unittest.TestCase,
FactsParamsTestCase):
def setUp(self):
self.configure_mocks(self, EnclosureFactsModule)
self.enclosures = self.mock_ov_client.enclosures
FactsParamsTestCase.configure_client_mock(self, self.enclosures)
def test_should_get_all_enclosures(self):
self.enclosures.get_all.return_value = PRESENT_ENCLOSURES
self.mock_ansible_module.params = PARAMS_GET_ALL
EnclosureFactsModule().run()
self.mock_ansible_module.exit_json.assert_called_once_with(
changed=False,
ansible_facts=dict(enclosures=(PRESENT_ENCLOSURES))
)
def test_should_get_enclosure_by_name(self):
self.enclosures.get_by.return_value = PRESENT_ENCLOSURES
self.mock_ansible_module.params = PARAMS_GET_BY_NAME
EnclosureFactsModule().run()
self.mock_ansible_module.exit_json.assert_called_once_with(
changed=False,
ansible_facts=dict(enclosures=(PRESENT_ENCLOSURES))
)
def test_should_get_enclosure_by_name_with_options(self):
self.enclosures.get_by.return_value = PRESENT_ENCLOSURES
self.enclosures.get_script.return_value = ENCLOSURE_SCRIPT
self.enclosures.get_utilization.return_value = ENCLOSURE_UTILIZATION
self.enclosures.get_environmental_configuration.return_value = ENCLOSURE_ENVIRONMENTAL_CONFIG
self.mock_ansible_module.params = PARAMS_GET_BY_NAME_WITH_OPTIONS
EnclosureFactsModule().run()
self.mock_ansible_module.exit_json.assert_called_once_with(
changed=False,
ansible_facts=dict(enclosures=PRESENT_ENCLOSURES,
enclosure_script=ENCLOSURE_SCRIPT,
enclosure_environmental_configuration=ENCLOSURE_ENVIRONMENTAL_CONFIG,
enclosure_utilization=ENCLOSURE_UTILIZATION)
)
def test_should_get_all_utilization_data(self):
self.enclosures.get_by.return_value = PRESENT_ENCLOSURES
self.enclosures.get_script.return_value = ENCLOSURE_SCRIPT
self.enclosures.get_utilization.return_value = ENCLOSURE_UTILIZATION
self.enclosures.get_environmental_configuration.return_value = ENCLOSURE_ENVIRONMENTAL_CONFIG
self.mock_ansible_module.params = PARAMS_GET_BY_NAME_WITH_OPTIONS
EnclosureFactsModule().run()
self.enclosures.get_utilization.assert_called_once_with(PRESENT_ENCLOSURES[0]['uri'], fields='', filter='',
view='', refresh='')
def test_should_get_utilization_with_parameters(self):
self.enclosures.get_by.return_value = PRESENT_ENCLOSURES
self.enclosures.get_script.return_value = ENCLOSURE_SCRIPT
self.enclosures.get_utilization.return_value = ENCLOSURE_UTILIZATION
self.enclosures.get_environmental_configuration.return_value = ENCLOSURE_ENVIRONMENTAL_CONFIG
self.mock_ansible_module.params = PARAMS_GET_UTILIZATION_WITH_PARAMS
EnclosureFactsModule().run()
date_filter = ["startDate=2016-06-30T03:29:42.000Z", "endDate=2016-07-01T03:29:42.000Z"]
self.enclosures.get_utilization.assert_called_once_with(
PRESENT_ENCLOSURES[0]['uri'], fields='AveragePower', filter=date_filter, view='day', refresh=True)
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,58 @@
# Copyright (c) 2016-2017 Hewlett Packard Enterprise Development LP
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from ansible.compat.tests import unittest
from oneview_module_loader import OneViewModuleBase
from ansible.modules.remote_management.oneview.oneview_logical_interconnect_group_facts import LogicalInterconnectGroupFactsModule
from hpe_test_utils import FactsParamsTestCase
ERROR_MSG = 'Fake message error'
PARAMS_GET_ALL = dict(
config='config.json',
name=None
)
PARAMS_GET_BY_NAME = dict(
config='config.json',
name="Test Logical Interconnect Group"
)
PRESENT_LIGS = [{
"name": "Test Logical Interconnect Group",
"uri": "/rest/logical-interconnect-groups/ebb4ada8-08df-400e-8fac-9ff987ac5140"
}]
class LogicalInterconnectGroupFactsSpec(unittest.TestCase, FactsParamsTestCase):
def setUp(self):
self.configure_mocks(self, LogicalInterconnectGroupFactsModule)
self.logical_interconnect_groups = self.mock_ov_client.logical_interconnect_groups
FactsParamsTestCase.configure_client_mock(self, self.logical_interconnect_groups)
def test_should_get_all_ligs(self):
self.logical_interconnect_groups.get_all.return_value = PRESENT_LIGS
self.mock_ansible_module.params = PARAMS_GET_ALL
LogicalInterconnectGroupFactsModule().run()
self.mock_ansible_module.exit_json.assert_called_once_with(
changed=False,
ansible_facts=dict(logical_interconnect_groups=(PRESENT_LIGS))
)
def test_should_get_lig_by_name(self):
self.logical_interconnect_groups.get_by.return_value = PRESENT_LIGS
self.mock_ansible_module.params = PARAMS_GET_BY_NAME
LogicalInterconnectGroupFactsModule().run()
self.mock_ansible_module.exit_json.assert_called_once_with(
changed=False,
ansible_facts=dict(logical_interconnect_groups=(PRESENT_LIGS))
)
if __name__ == '__main__':
unittest.main()

View File

@ -20,10 +20,14 @@ from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
import string
import textwrap
from ansible import constants as C
from ansible.compat.tests import mock
from ansible.compat.tests import unittest
from ansible.module_utils.six import string_types
from ansible.module_utils._text import to_text
from units.mock.path import mock_unfrackpath_noop
from ansible.inventory.manager import InventoryManager, split_host_pattern
@ -156,6 +160,22 @@ class IniInventory(unittest.TestCase):
else:
self.assertIsInstance(variables['var%s' % i], type(values[i]))
@mock.patch('ansible.inventory.manager.unfrackpath', mock_unfrackpath_noop)
@mock.patch('os.path.exists', lambda x: True)
@mock.patch('os.access', lambda x, y: True)
def test_yaml_inventory(self, filename="test.yaml"):
inventory_content = {filename: textwrap.dedent("""\
---
all:
hosts:
test1
test2
""")}
C.INVENTORY_ENABLED = ['yaml']
fake_loader = DictDataLoader(inventory_content)
im = InventoryManager(loader=fake_loader, sources=filename)
self.assertTrue(im._inventory.hosts)
def _get_inventory(self, inventory_content):
fake_loader = DictDataLoader({__file__: inventory_content})