Compare commits
31 Commits
threading_
...
threading_
| Author | SHA1 | Date | |
|---|---|---|---|
| 847327eb9a | |||
| ba0b91b51b | |||
| 2d70dc7f21 | |||
| 235d139e5d | |||
| dae0ad1ce6 | |||
| 278ff19bea | |||
| cf3414d7d7 | |||
| 101377768b | |||
| 9b693235f0 | |||
| a12a05c219 | |||
| 17fbeeb2f0 | |||
| 4a358b5396 | |||
| db70eeb913 | |||
| d0c003ab0f | |||
| 89799bbb98 | |||
| ef25367353 | |||
| 2804a2663a | |||
| 46fd083138 | |||
| 12a4dca447 | |||
| 7d74c126a9 | |||
| 67fd98da09 | |||
| 44f5b2bd25 | |||
| af3e8950d6 | |||
| 6d3cbbfc38 | |||
| c055795e02 | |||
| 1241d0a3f4 | |||
| a71ca66e6e | |||
| 78fd326908 | |||
| 9ae159dfa4 | |||
| d6737dcdd4 | |||
| d313c2d5e9 |
2
.github/BOTMETA.yml
vendored
2
.github/BOTMETA.yml
vendored
@ -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
|
||||
|
||||
@ -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')
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
| \```
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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
|
||||
----------------
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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:
|
||||
|
||||
35
lib/ansible/executor/shared_plugin_loader.py
Normal file
35
lib/ansible/executor/shared_plugin_loader.py
Normal 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
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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):
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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')
|
||||
|
||||
@ -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',
|
||||
|
||||
@ -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 ""
|
||||
|
||||
|
||||
|
||||
@ -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 ""
|
||||
|
||||
|
||||
|
||||
@ -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 ""
|
||||
|
||||
|
||||
|
||||
@ -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']
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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()
|
||||
@ -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()
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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')
|
||||
|
||||
@ -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')
|
||||
|
||||
@ -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')
|
||||
|
||||
@ -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')
|
||||
|
||||
@ -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():
|
||||
|
||||
@ -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():
|
||||
|
||||
@ -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():
|
||||
|
||||
@ -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')
|
||||
|
||||
@ -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():
|
||||
|
||||
@ -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')
|
||||
|
||||
@ -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')
|
||||
|
||||
@ -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')
|
||||
|
||||
@ -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')
|
||||
|
||||
@ -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')
|
||||
|
||||
@ -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')
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
'''
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
2
lib/ansible/plugins/cache/redis.py
vendored
2
lib/ansible/plugins/cache/redis.py
vendored
@ -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)
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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")
|
||||
|
||||
|
||||
@ -51,7 +51,6 @@ options:
|
||||
|
||||
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "ansible-tower-cli >= 3.0.2"
|
||||
|
||||
notes:
|
||||
|
||||
@ -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() {
|
||||
|
||||
@ -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 .
|
||||
|
||||
@ -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 && :
|
||||
|
||||
@ -1,3 +1,2 @@
|
||||
posix/ci/cloud/group1/vcenter
|
||||
cloud/vcenter
|
||||
destructive
|
||||
|
||||
1
test/integration/targets/win_dotnet_ngen/aliases
Normal file
1
test/integration/targets/win_dotnet_ngen/aliases
Normal file
@ -0,0 +1 @@
|
||||
windows/ci/group1
|
||||
20
test/integration/targets/win_dotnet_ngen/tasks/main.yml
Normal file
20
test/integration/targets/win_dotnet_ngen/tasks/main.yml
Normal 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"
|
||||
@ -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'"
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 = ''
|
||||
|
||||
@ -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):
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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()
|
||||
@ -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()
|
||||
@ -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})
|
||||
Reference in New Issue
Block a user