Commit Graph

420 Commits (f88dedb39d70abeab2e291bd7d07d38b44f4b966)

Author SHA1 Message Date
Trishna Guha 2e8a3efccb
Revert nxos, ios, iosxr return_timestamps (#56206)
* Revert "nxos_command:run_commands results failure when commands array size >1 (#52670)"
This reverts commit 0df5b92af3.
* Revert "added timestamps to nxos_command module (#50261)"
This reverts commit e150943314.
* Revert "added timestamps to ios_command module (#50323)"
This reverts commit 2a432a093b.
* Revert "added response_timestamps to iosxr_command module (#50095)"
This reverts commit 2a0c356da9.
2019-05-08 20:49:29 +05:30
Brian Coca bda541fa0d
fix missing attribs with dirct module execution (#53875)
* fix missing attribs with dirct module execution
* also make remote tmp handling smarter
 update tests
* set default if attrib does not exist
* add simple test
2019-04-04 09:59:52 -04:00
Matt Clay 56418cc274 Fix file path encoding bugs on Python 3. 2019-03-28 08:54:49 -07:00
Sam Doran ff88bd82b5
Move type checking methods out of basic.py and add unit tests (#53687)
* Move check_type_str() out of basic.py

* Move check_type_list() out of basic.py

* Move safe_eval() out of basic.py

* Move check_type_dict() out of basic.py

* Move json importing code to common location

* Move check_type_bool() out of basic.py

* Move _check_type_int() out of basic.py

* Move _check_type_float() out of basic.py

* Move _check_type_path() out of basic.py

* Move _check_type_raw() out of basic.py

* Move _check_type_bytes() out of basic.py

* Move _check_type_bits() out of basic.py

* Create text.formatters.py

Move human_to_bytes, bytes_to_human, and _lenient_lowercase out of basic.py into text.formatters.py
Change references in modules to point to function at new location

* Move _check_type_jsonarg() out of basic.py

* Rename json related functions and put them in common.text.converters

Move formatters.py to common.text.formatters.py and update references in modules.

* Rework check_type_str()

Add allow_conversion option to make the function more self-contained.
Move the messaging back to basic.py since those error messages are more relevant to using this function in the context of AnsibleModule and not when using the function in isolation.

* Add unit tests for type checking functions

* Change _lenient_lowercase to lenient_lowercase per feedback
2019-03-21 09:40:19 -04:00
Sam Doran 43a44e6f35
Move utility functions out of basic.py (#51715)
Move the following methods to lib/anisble/module_utils/common/validation.py:

- _count_terms()
- _check_mutually_exclusive()
- _check_required_one_of()
- _check_required_together()
- _check_required_by()
- _check_required_arguments()
- _check_required_if
- fail_on_missing_params() --> create check_missing_parameters()
2019-03-14 21:29:55 -04:00
Brian Coca e280f2f7b0
Try to get correct buffer size to avoid races (#53547)
* Try to get correct buffer size to avoid races

  fixes #51393

* fix test, mock buffer function since all is mocked
2019-03-14 11:04:56 -04:00
Felix Fontein 07fcb60d55 Python 2: accept both long and int for type=int (module options) (#53289)
* Added unit test
2019-03-05 09:39:03 -05:00
Sam Doran aba4bed803
Move _handle_no_log_values() out of basic.py (#48628)
* Rename method and make private
* Use is_iterable, combine transformations
* Remove unused return_values from network modules
* Improve docstrings in new functions
* Add new PASS_VAR
* Add unit tests for list_no_log_values
* Fix unit tests for Python 2.6
2019-03-04 17:02:44 -05:00
Sam Doran 2a98faee2b
Move _handle_aliases() out of basic.py (#48578)
Refinements:
- return legal_inputs and update class properties
- remove redundant arguments from method and handle in caller
- add better exception types to method

* Add unit tests for handle_aliases
2019-02-28 16:43:19 -05:00
Sam Doran 23a6b88dd2
Modify the correct variable when setting available hashing algorithms (#52994)
* Revert "use list instead of tuple and remove md5 on ValueError (#51357)" c459f040da.
* Modify the correct variable when determining available hashing algorithms
2019-02-28 07:32:00 -05:00
Sam Doran cc9c72d6f8 Do not add state: absent when a non-existent path is returned (#51350)
Leave it up to the module to return the state in the results.

I went through all the modules in files/ and only found one case where the module needed to return this. No other modules return paths that do not exists.

Signed-off-by: Sam Doran <sdoran@redhat.com>
2019-02-23 01:48:44 +01:00
Sam Doran f52a088862
Add option to ignore, warn, or error when a module parameter is converted to a string (#51404)
* Add new module property to Windows modules
* Add brief pause to file tests to ensure the stat times are not equal, which was happening sometimes.
* Raise TypeError on error rather than fail_json()
* Rework error message to be less verbose
* Add porting guide entry
2019-02-22 16:44:32 -05:00
Ganesh Nalawade 41e2bd1df5
Add support for elements validation in argspec (#50335)
* Add support for elements validation in argspec

Fixes #48473

*  Add support to validate the elements value in argspec
   when type is `list`

* Fix unit test failures

* Add unit test for elements validation

* Fix CI failures

* Fix review comments

* Fix unit test and CI failures after rebase
2019-02-19 17:35:20 +05:30
Dag Wieers c2fb581414 Fix various sonarcloud issues
This fixes various reported bugs through sonarcloud at:
https://sonarcloud.io/project/issues?id=Rodney-Reis_ansible&resolved=false&types=BUG
2019-02-15 07:19:04 -08:00
Dag Wieers cd9471ef17 Introduce new 'required_by' argument_spec option (#28662)
* Introduce new "required_by' argument_spec option

This PR introduces a new **required_by** argument_spec option which allows you to say *"if parameter A is set, parameter B and C are required as well"*.

- The difference with **required_if** is that it can only add dependencies if a parameter is set to a specific value, not when it is just defined.
- The difference with **required_together** is that it has a commutative property, so: *"Parameter A and B are required together, if one of them has been defined"*.

As an example, we need this for the complex options that the xml module provides. One of the issues we often see is that users are not using the correct combination of options, and then are surprised that the module does not perform the requested action(s).

This would be solved by adding the correct dependencies, and mutual exclusives. For us this is important to get this shipped together with the new xml module in Ansible v2.4. (This is related to bugfix https://github.com/ansible/ansible/pull/28657)

```python
    module = AnsibleModule(
        argument_spec=dict(
            path=dict(type='path', aliases=['dest', 'file']),
            xmlstring=dict(type='str'),
            xpath=dict(type='str'),
            namespaces=dict(type='dict', default={}),
            state=dict(type='str', default='present', choices=['absent',
'present'], aliases=['ensure']),
            value=dict(type='raw'),
            attribute=dict(type='raw'),
            add_children=dict(type='list'),
            set_children=dict(type='list'),
            count=dict(type='bool', default=False),
            print_match=dict(type='bool', default=False),
            pretty_print=dict(type='bool', default=False),
            content=dict(type='str', choices=['attribute', 'text']),
            input_type=dict(type='str', default='yaml', choices=['xml',
'yaml']),
            backup=dict(type='bool', default=False),
        ),
        supports_check_mode=True,
        required_by=dict(
            add_children=['xpath'],
            attribute=['value', 'xpath'],
            content=['xpath'],
            set_children=['xpath'],
            value=['xpath'],
        ),
        required_if=[
            ['count', True, ['xpath']],
            ['print_match', True, ['xpath']],
        ],
        required_one_of=[
            ['path', 'xmlstring'],
            ['add_children', 'content', 'count', 'pretty_print', 'print_match', 'set_children', 'value'],
        ],
        mutually_exclusive=[
            ['add_children', 'content', 'count', 'print_match','set_children', 'value'],
            ['path', 'xmlstring'],
        ],
    )
```

* Rebase and fix conflict

* Add modules that use required_by functionality

* Update required_by schema

* Fix rebase issue
2019-02-15 10:57:45 +10:00
Jordan Borean a39c4ad464
Final round of moving modules to new import error msg (#51852)
* Final round of moving modules to new import error msg

* readd URL to jenkins install guide

* fix unit tests
2019-02-08 10:07:01 +10:00
Mike Sgarbossa c459f040da use list instead of tuple and remove md5 on ValueError (#51357)
* use list instead of tuple and remove md5 on ValueError

Signed-off-by: michael.sgarbossa <msgarbossa@cvs.com>

* convert algorithms to list and add comment

Signed-off-by: michael.sgarbossa <msgarbossa@cvs.com>

* only convert to list if algorithms is not None

Signed-off-by: michael.sgarbossa <msgarbossa@cvs.com>

* new fragment for PR 51357

Signed-off-by: michael.sgarbossa <msgarbossa@cvs.com>

* fix lint: remove blank line
2019-02-07 11:23:11 -05:00
Jordan Borean 0f0d33a954 start getting modules to use shared import error code (#51787) 2019-02-06 12:39:17 -05:00
vaneuk e150943314 added timestamps to nxos_command module (#50261)
* added timestamps to nxos_command module

nxos_command module now returns timestamps field, which shows command execution time

* –fixed unit test failure for /lib/ansible/module_utils/basic

* cosmetic changes to align with PEP 8
2019-01-17 10:14:31 +05:30
Toshio Kuratomi 5844c8c7f0 Cleanups to the common.sys_info API
* Move get_all_subclasses out of sys_info as it is unrelated to system
  information.
* get_all_subclasses now returns a set() instead of a list.
* Don't port get_platform to sys_info as it is deprecated.  Code using
  the common API should just use platform.system() directly.
* Rename load_platform_subclass() to get_platform_subclass and do not
  instantiate the rturned class.
* Test the compat shims in module_utils/basic.py separately from the new
  API in module_utils/common/sys_info.py and module_utils/common/_utils.py
2019-01-03 16:21:09 -08:00
Toshio Kuratomi bd072fe83a
Make the timeout decorator raise an exception out of the function's scope (#49921)
* Revert "allow caller to deal with timeout (#49449)"

This reverts commit 63279823a7.

Flawed on many levels

* Adds poor API to a public function
* Papers over the fact that the public function is doing something bad
  by catching exceptions it cannot handle in the first place
* Papers over the real cause of the issue which is a bug in the timeout
  decorator
* Doesn't reraise properly
* Catches the wrong exception

Fixes #49824
Fixes #49817

* Make the timeout decorator properly raise an exception outside of the function's scope

signal handlers which raise exceptions will never work well because the
exception can be raised anywhere in the called code.  This leads to
exception race conditions where the exceptions could end up being
hanlded by unintended pieces of the called code.

The timeout decorator was using just that idiom.  It was especially bad
because the decorator syntactically occurs outside of the called code
but because of the signal handler, the exception was being raised inside
of the called code.

This change uses a thread instead of a signal to manage the timeout in
parallel to the execution of the decorated function.  Since raising of
the exception happens inside of the decorator, now, instead of inside of
a signal handler, the timeout exception is raised from outside of the
called code as expected which makes reasoning about where exceptions are
to be expected intuitive again.

Fixes #43884

* Add a common case test.

Adding an integration test driven from our unittests.  Most of the time
we'll timeout in run_command which is running things in a subprocess.
Create a test for that specific case in case anything funky comes up
between threading and execve.

* Don't use OSError-based TimeoutError as a base class

Unlike most standard exceptions, OSError has a specific parameter list
with specific meanings.  Instead follow the example of other stdlib
functions, concurrent.futures and multiprocessing and define a separate
TimeoutException.

* Add comment and docstring to point out that this is not hte Python3 TimeoutError
2018-12-18 18:01:46 -08:00
Toshio Kuratomi 3fba006207 Update bare exceptions to specify Exception.
This will keep us from accidentally catching program-exiting exceptions
like KeyboardInterupt and SystemExit.
2018-12-16 15:03:19 -08:00
Brian Coca 63279823a7
allow caller to deal with timeout (#49449)
* allow caller to deal with timeout

  a start for #43884 and timeout issues in long operations
2018-12-11 15:21:18 -05:00
Andreas Krüger 18bf48cec2 Pull documentation of ansible.module_utils.basic from (improved) doc strings. (#48416) 2018-12-10 09:17:15 -06:00
Andreas Calminder 876b637208 move some of basic into common (#48078)
* move file functions into common.file

* move *_PERM_BITS and mark as private (_*_PERM_BITS)

* move get_{platform, distribution, distribution_version} get_all_subclasses and load_platform_subclass into common.sys_info

* forgot get_distribution_version, properly rename get_all_subclasses

* add common/sys_info.py to recursive finder test

* update module paths in test_platform_distribution.py

* update docstrings, _get_all_subclasses -> get_all_subclasses

* forgot to update names

* remove trailing whitespace
2018-12-07 10:21:11 -08:00
Abhijeet Kasurde 789b0ef0c9 Pass string command in run_command (#48805)
When there are spaces in command args passed as a list,
then run_command and underlying subprocess fails.
This can be overcome by passing command as string rather than list.

Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
2018-11-20 00:01:54 -05:00
Yauhen Kirylau 14037443de fix(tasks: synchronize): wrap in sshpass if ssh password was provided (#30743)
* fix(tasks: synchronize): wrap in sshpass if ssh password was provided

Closes #16616

* fix(tasks: synchronize): pass rsync password to sshpass via fd

* fix(tasks: synchronize): use fail_json instead of AnsibleError

* fixup! fix(tasks: synchronize): use fail_json instead of AnsibleError

fix python2 handling

* feat(module_utils: basic: run_command): add optional arguments `pass_fds` and `before_communicate_callback`

* fix(tasks: synchronize): use module.run_command instead of subprocess.Popen

* fixup! fix(tasks: synchronize): use module.run_command instead of subprocess.Popen

remove unused import

* fixup! fixup! fix(tasks: synchronize): use module.run_command instead of subprocess.Popen

pass_fds only if they passed to run_command()
2018-11-05 15:00:34 -05:00
Jordan Borean ddfd1dbfc6
Add helper function to return helpful import error msg (#47409) 2018-10-24 07:21:36 +10:00
Jonathan Oddy f2dccb90e8 Restore SIGPIPE handler to DFL on POpen
Python sets the SIGPIPE handler to SIG_IGN. On execv() signal handlers are
reset to their defaults, EXCEPT those that are SIG_IGN which are left ignored.
In Python 3 subprocess.popen explicitly resets the SIGPIPE handler to SIG_DFL,
but unfortunately in Python 2.7 it does not. This leads to subprocesses being
executed with SIGPIPE ignored. This is often a problem with bash scripts which
rely on SIGPIPE to terminate commands in a pipe, but can easily be a problem
with other applications.

This implements the Python 3 behaviour for Python 2.7 by using a preexec_fn.
2018-10-12 12:31:24 -07:00
Dag Wieers 66eec42f53 Fix calling deprecate with correct arguments (#44726)
This fixes #44702
2018-09-21 12:30:31 -04:00
Sviatoslav Sydorenko a978d7f283 Fix collections.deque import in compat module 2018-09-19 13:14:24 +03:00
Matt Martz 07b2698c03 Add new expand_shell argument for run_command, to disable expanding shellisms (#45620)
* Add new expand_shell argument for run_command, to disable expanding shellisms. Fixes #45418

* s/expand_shell/expand_user_and_vars/g
2018-09-14 16:07:11 -04:00
Jordan Borean e07352b9de basic.py: catch ValueError when trying to import hash algorithms (#44551)
* basic.py: catch more Exceptions when trying to import md5 hash algorithms
2018-08-22 23:34:50 -07:00
Matt Martz c1c229c6d4
Remove use of simplejson throughout code base (#43548)
* Remove use of simplejson throughout code base. Fixes #42761

* Address failing tests

* Remove simplejson from contrib and other outlying files

* Add changelog fragment for simplejson removal
2018-08-10 11:13:29 -05:00
Brian Coca 222c907ffb
actually check we can run scm command for roles (#43315)
* actually check we can run scm command for roles
* a better error message than file not found
* more narrow exception hanlding
* refactor common functions for more extended use and further 'basic.py' separation
2018-07-31 13:04:05 -04:00
Toshio Kuratomi 52449cc01a AnsiballZ improvements
Now that we don't need to worry about python-2.4 and 2.5, we can make
some improvements to the way AnsiballZ handles modules.

* Change AnsiballZ wrapper to use import to invoke the module
  We need the module to think of itself as a script because it could be
  coded as:

      main()

  or as:

      if __name__ == '__main__':
          main()

  Or even as:

      if __name__ == '__main__':
          random_function_name()

  A script will invoke all of those.  Prior to this change, we invoked
  a second Python interpreter on the module so that it really was
  a script.  However, this means that we have to run python twice (once
  for the AnsiballZ wrapper and once for the module).  This change makes
  the module think that it is a script (because __name__ in the module ==
  '__main__') but it's actually being invoked by us importing the module
  code.

  There's three ways we've come up to do this.
  * The most elegant is to use zipimporter and tell the import mechanism
    that the module being loaded is __main__:
    * 5959f11c9d/lib/ansible/executor/module_common.py (L175)
    * zipimporter is nice because we do not have to extract the module from
      the zip file and save it to the disk when we do that.  The import
      machinery does it all for us.
    * The drawback is that modules do not have a __file__ which points
      to a real file when they do this.  Modules could be using __file__
      to for a variety of reasons, most of those probably have
      replacements (the most common one is to find a writable directory
      for temporary files.  AnsibleModule.tmpdir should be used instead)
      We can monkeypatch __file__ in fom AnsibleModule initialization
      but that's kind of gross.  There's no way I can see to do this
      from the wrapper.

  * Next, there's imp.load_module():
    * https://github.com/abadger/ansible/blob/340edf7489/lib/ansible/executor/module_common.py#L151
    * imp has the nice property of allowing us to set __name__ to
      __main__ without changing the name of the file itself
    * We also don't have to do anything special to set __file__ for
      backwards compatibility (although the reason for that is the
      drawback):
    * Its drawback is that it requires the file to exist on disk so we
      have to explicitly extract it from the zipfile and save it to
      a temporary file

  * The last choice is to use exec to execute the module:
    * https://github.com/abadger/ansible/blob/f47a4ccc76/lib/ansible/executor/module_common.py#L175
    * The code we would have to maintain for this looks pretty clean.
      In the wrapper we create a ModuleType, set __file__ on it, read
      the module's contents in from the zip file and then exec it.
    * Drawbacks: We still have to explicitly extract the file's contents
      from the zip archive instead of letting python's import mechanism
      handle it.
    * Exec also has hidden performance issues and breaks certain
      assumptions that modules could be making about their own code:
      http://lucumr.pocoo.org/2011/2/1/exec-in-python/

  Our plan is to use imp.load_module() for now, deprecate the use of
  __file__ in modules, and switch to zipimport once the deprecation
  period for __file__ is over (without monkeypatching a fake __file__ in
  via AnsibleModule).

* Rename the name of the AnsiBallZ wrapped module
  This makes it obvious that the wrapped module isn't the module file that
  we distribute.  It's part of trying to mitigate the fact that the module
  is now named __main)).py in tracebacks.

* Shield all wrapper symbols inside of a function
  With the new import code, all symbols in the wrapper become visible in
  the module.  To mitigate the chance of collisions, move most symbols
  into a toplevel function.  The only symbols left in the global namespace
  are now _ANSIBALLZ_WRAPPER and _ansiballz_main.

revised porting guide entry

Integrate code coverage collection into AnsiballZ.

ci_coverage
ci_complete
2018-07-26 20:07:25 -07:00
Dag Wieers 9bf22309b3 Clarify uncertain nature of tracebacks on Python 2 (#42513)
* Only add exception/traceback on Python 3

On Python 2 the traceback could be any exception from the stack frame
and likely unrelated to the fail_json call.

On Python 3 the traceback is cleared outside any exception frame, so the
call always returns the most inner traceback (if any), and therefor is
most likely related to the fail_json call.

* Add uncertainty to traceback on Python 2

On Python 2 the last exception in the stack frame is being returned,
this could be unrelated to the actual error, especially if fail_json()
is called outside an except: block.
2018-07-25 11:49:16 -04:00
Brian Coca 9217fbb7dd
better error messasge (#42770)
* better error messasge
2018-07-19 12:13:09 -04:00
Jordan Borean 8bdd04c147 Fix remote_tmp when become with non admin user (#42396)
* Fix tmpdir on non root become

 - also avoid exception if tmpdir and remote_tmp are None
 - give 'None' on deescalation so tempfile will fallback to it's default behaviour
   and use system dirs
 - fix issue with bad tempdir (not existing/not createable/not writeable)
   i.e nobody and ~/.ansible/tmp
 - added tests for blockfile case

* Revert "Temporarily revert c119d54"

This reverts commit 5c614a59a6.

* changes based on PR feedback and changelog fragment

* changes based on the review

* Fix tmpdir when makedirs failed so we just use the system tmp

* Let missing remote_tmp fail

If remote_tmp is missing then there's something more basic wrong in the
communication from the controller to the module-side.  It's better to
be alerted in this case than to silently ignore it.

jborean and I have independently checked what happens if the user sets
ansible_remote_tmp to empty string and !!null and both cases work fine.
(null is turned into a default value controller-side.  empty string
triggers the warning because it is probably not a directory that the
become user is able to use).
2018-07-06 10:49:19 -07:00
Abhijeet Kasurde 087fc0c20c Restore BOOLEANS import in basic.py (#42008)
This import was removed by mistake. This is required for backward
compatibility.

Fixes: #41988

Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
2018-07-02 10:27:16 -04:00
Andreas Calminder 75e9b76c15 accept + and - modifiers for file attributes (#40061)
* accept + and - modifiers for file attributes
* tests for adding/removing file attributes
2018-06-14 06:31:14 -07:00
Hideki Saito d7df072b96 Add syslog_facility parameter handling with systemd.journal (#41078)
* Add syslog_facility parameter handling with systemd.journal

- Fixed issue #41072

Signed-off-by: Hideki Saito <saito@fgrep.org>
2018-06-07 12:23:13 -07:00
Sviatoslav Sydorenko eb209e92c9 Move collections abc shim to _collections_compat 2018-05-27 02:23:57 +02:00
Sviatoslav Sydorenko 912bd25a4e Drop deprecated Python 2.4 compat shim 2018-05-27 02:23:57 +02:00
Sviatoslav Sydorenko e1ae082a1e Partially python3fy ansible.module_utils.basic
Adding
    __metaclass__ = type
breaks things, so I didn't include it.
2018-05-27 02:23:57 +02:00
Toshio Kuratomi 3760cc3a7d Fix python-2.4ism that was still present in basic.py's use of tempfile 2018-05-17 15:24:56 -07:00
Jordan Borean 5c39c3b2d1
Module basic.py to create parent dirs of tmpdir if needed (#40201)
* Module basic.py to create parent dirs of tmpdir if needed

* Added warning to dir creation

* Assert if make_dirs was called or not in unit tests
2018-05-17 09:52:46 +10:00
Jordan Borean 44ab948e5d
create module tmpdir based on remote_tmp (#39833)
* create module tmpdir based on remote_tmp

* Source remote_tmp from controller if possible

* Fixed sanity test and not use lambda

* Added expansion of env vars to the remote tmp

* Fixed sanity issues

* Added note around shell remote_tmp option

* Changed fallback tmp dir to ~/.ansible/tmp to make shell defaults
2018-05-15 09:31:21 +10:00
Toshio Kuratomi e17ee368e3 Improve comments about file_commmon_arguments 2018-05-11 06:35:03 -07:00
Toshio Kuratomi 6b6c4914d2 Initial cleanup of file module
* Remove use of six.b as Python-2.6+ have byte literals.
* Make AnsibleModule a global object so we'll have access to it in all
  the functions we're going to break this up into.
* Rework the parameters so things that are in file_common_args are used
  from file_common_args or the reason for deviation is documented.
* Remove validate as a parameter: this should be taken care of by
  removing it from params before the copy and template action plugin
  invoke file.
* Rename diff_peek to _diff_peek as it is an internal parameter.
* add module_name execute_module call to assemble so that it is more greppable
2018-05-10 14:48:28 -07:00