Ensure we force mtime/atime update when using copystat
Co-authored-by: Sloane Hertel <19572925+s-hertel@users.noreply.github.com>
Co-authored-by: Brian Coca <bcoca@users.noreply.github.com>
* fix creating file in directory with setgid bit
* add a test using the copy module's content option to create a file in a directory with setgid bit
Co-authored-by: Martin Krizek <martin.krizek@gmail.com>
* use copystat to copy as many attributes as possible before os.rename
update unit test mocks for updated method of attribute preservation
add integration test for lineinfile case
remove erroneous `- meta: end_play` from lineinfile test suite
* add keep_dest_attrs parameter to control whether src attributes are
copied initially, and for existing destinations, whether the src is
updated using the dest before being renamed
consolidate with copy unsetting extended attrs
ci_complete
* ValueError exception is raised when Null Character is sent
to syslog.syslog with Python 3.12.
* Handle this error gracefully instead of stacktrace
Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
Adds an option that can have an action plugin tell the module to ignore
options that do not fit its arg spec. This is to enable support for core
running modules that exist outside of the collection that may not be new
enough to support some of the options supplied to it.
* Reword the error message when the module fails to parse parameters
in JSON format
* misc typo fixes
Fixes: #81188
Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
* Back out use of communicate, add better comments, add bufsize, and align with subprocess._communicate
* tests
* re-order logic slightly
* more comments
* loopty loop
* yet another comment
* Revert "yet another comment"
This reverts commit 96cd8ada5fa0441b92f2298bdaa6cb40594847d2.
* Revert "loopty loop"
This reverts commit 96ea066f6a7d18902c04a14f18dd79b38e56f5e7.
* ci_complete
* Copy in comment too
* Wording updates
Co-authored-by: Matt Davis <6775756+nitzmahone@users.noreply.github.com>
* Back out bufsize
---------
Co-authored-by: Matt Davis <6775756+nitzmahone@users.noreply.github.com>
* Symbolic modes with X or =[ugo] always use original mode (Fixes#80128)
Here's what's happening, by way of this mode example: u=,u=rX
At the first step in the loop, the "u" bits of are set to 0. On the next
step in the loop, the current stat of the filesystem object is used to
determine X, not the "new_mode" in the previous iteration of the loop. So
while most operations kind of operate left to right, "X" is always going
back to the original file to determine whether to set x bit.
The Linux "chmod" (the only one I've tested) doesn't operate this way. In
it, "X" operates on the current state the loop understands it is in,
based on previous operations (and starting with the file permissions).
This is an issue with "X" and any of the "=[ugo]" settings, because
they are lookups. For example, if a file is 755 and you do "ug=rx,o=u",
file module produces 0557 and chmod produces 0555.
This really becomes a problem when you want to recursively change a
directory of files, and the files are currently 755, but you want to
change the directory to 750 and the files to 640. In chmod you can do
"a=,ug=rX,u+w" (or "a=,u=rwX,g=rX"), and have it apply equally to the
directory and the files. I can't come up with a single way in the ansible
file module to deterministically, recursively, set a directory to 750
and the contents to 640 no matter what the current permissions are,
as the code currently is.
The fix is to pass in "new_mode" to _get_octal_mode_from_symbolic_perms
in lib/ansible/module_utils/basic.py inside _symbolic_mode_to_octal. And
then take "new_mode" as an argument and use it instead of the filesystem
object stat.st_mode value.
* Fixing my new unit test, fixing bug in test comments
* Fix detection of available hashlib algorithms
Detection of hashlib algorithms now works on Python 3.x.
The new implementation works on Python 2.7 and later.
Test coverage is provided by both integration and unit tests.
* Add additional details about hashlib in docs
* Update `collections.abc` imports
- Use `six.moves` for modules and module_utils
- Use `collections.abc` for controller code
This avoids using `ansible.module_utils.common._collections_compat`,
which was added before the vendored `six` was updated to provide these
imports.
* Update _collections_compat to use six.moves
Also update the custom pylint rule to reflect this change.
When looking up the `no_log` setting for a parameter that is an alias in
`AnsibleModule._log_invocation()`, the alias value will always be an
empty dictionary since `self.aliases` on the `AnsibleModule` instance is
never updated after initialization. Since the `no_log` setting is on the
canonical parameter not the alias, an incorrect warning is issued if the
parameter matches `PASSWORD_MATCH`.
This PR returns the aliases dictionary as an attribute of the
`ValidationResult` and updates the `aliases` attribute on the
`AnsibleModule` instance.
* user - Remove unused code.
* Replace deprecated abstractproperty decorator.
* Fix __all__ to be a tuple.
* Use a generator in subelements lookup.
* Use from import in basic.py
* Add changelog fragment.
* Fix selinux unit test.
* modules moved to use best_parsable_locale
* fixed invocations
* better better
* also module_utils
* converted to function as per fb
* patch testt
* whitespace
specially for when you have parameters in unicode but need
to scrape responses, C is still the fallback
Co-authored-by: Abhijeet Kasurde <akasurde@redhat.com>
* Don't mutate os.environ in AnsibleModule.run_command, make a copy, and pass to Popen. Fixes#74783
* Simplify code a bit
* More simple
* Address some other potentially non threadsafe operations
* Add if around umask
* Address unit test assumptions
* Add clog frag
* yaml syntax issue
* docs: Update Python 2 doc links
Update links from Python 2 to Python 3
Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
* use docs.python.com/3/ everywhere, except onethat should remain 2.6
* refer to python 3 in module docs and comments
* format two python docs links as list
* updates links in unwanted.py test file
* per matt clay, this should link to python 2
Co-authored-by: Alicia Cozine <acozine@users.noreply.github.com>
While logging, journal.send accepts module parameters.
If module parameters similar to arguments in journal.send,
rename the parameter names before sending to journal.send
Signed-off-by: Abhijeet Kasurde <akasurde@redhat.com>
* Begin using ArgumentSpecValidator in AnsibleModule
* Add check parameters to ArgumentSpecValidator
Add additional parameters for specifying required and mutually exclusive parameters.
Add code to the .validate() method that runs these additional checks.
* Make errors related to unsupported parameters match existing behavior
Update the punctuation in the message slightly to make it more readable.
Add a property to ArgumentSpecValidator to hold valid parameter names.
* Set default values after performining checks
* FIx sanity test failure
* Use correct parameters when checking sub options
* Use a dict when iterating over check functions
Referencing by key names makes things a bit more readable IMO.
* Fix bug in comparison for sub options evaluation
* Add options_context to check functions
This allows the parent parameter to be added the the error message if a validation
error occurs in a sub option.
* Fix bug in apply_defaults behavior of sub spec validation
* Accept options_conext in get_unsupported_parameters()
If options_context is supplied, a tuple of parent key names of unsupported parameter will be
created. This allows the full "path" to the unsupported parameter to be reported.
* Build path to the unsupported parameter for error messages.
* Remove unused import
* Update recursive finder test
* Skip if running in check mode
This was done in the _check_arguments() method. That was moved to a function that has no
way of calling fail_json(), so it must be done outside of validation.
This is a silght change in behavior, but I believe the correct one.
Previously, only unsupported parameters would cause a failure. All other checks would not be executed
if the modlue did not support check mode. This would hide validation failures in check mode.
* The great purge
Remove all methods related to argument spec validation from AnsibleModule
* Keep _name and kind in the caller and out of the validator
This seems a bit awkward since this means the caller could end up with {name} and {kind} in
the error message if they don't run the messages through the .format() method
with name and kind parameters.
* Double moustaches work
I wasn't sure if they get stripped or not. Looks like they do. Neat trick.
* Add changelog
* Update unsupported parameter test
The error message changed to include name and kind.
* Remove unused import
* Add better documentation for ArgumentSpecValidator class
* Fix example
* Few more docs fixes
* Mark required and mutually exclusive attributes as private
* Mark validate functions as private
* Reorganize functions in validation.py
* Remove unused imports in basic.py related to argument spec validation
* Create errors is module_utils
We have errors in lib/ansible/errors/ but those cannot be used by modules.
* Update recursive finder test
* Move errors to file rather than __init__.py
* Change ArgumentSpecValidator.validate() interface
Raise AnsibleValidationErrorMultiple on validation error which contains all AnsibleValidationError
exceptions for validation failures.
Return the validated parameters if validation is successful rather than True/False.
Update docs and tests.
* Get attribute in loop so that the attribute name can also be used as a parameter
* Shorten line
* Update calling code in AnsibleModule for new validator interface
* Update calling code in validate_argument_spec based in new validation interface
* Base custom exception class off of Exception
* Call the __init__ method of the base Exception class to populate args
* Ensure no_log values are always updated
* Make custom exceptions more hierarchical
This redefines AnsibleError from lib/ansible/errors with a different signature since that cannot
be used by modules. This may be a bad idea. Maybe lib/ansible/errors should be moved to
module_utils, or AnsibleError defined in this commit should use the same signature as the original.
* Just go back to basing off Exception
* Return ValidationResult object on successful validation
Create a ValidationResult class.
Return a ValidationResult from ArgumentSpecValidator.validate() when validation is successful.
Update class and method docs.
Update unit tests based on interface change.
* Make it easier to get error objects from AnsibleValidationResultMultiple
This makes the interface cleaner when getting individual error objects contained in a single
AnsibleValidationResultMultiple instance.
* Define custom exception for each type of validation failure
These errors indicate where a validation error occured. Currently they are empty but could
contain specific data for each exception type in the future.
* Update tests based on (yet another) interface change
* Mark several more functions as private
These are all doing rather "internal" things. The ArgumentSpecValidator class is the preferred
public interface.
* Move warnings and deprecations to result object
Rather than calling deprecate() and warn() directly, store them on the result object so the
caller can decide what to do with them.
* Use subclass for module arg spec validation
The subclass uses global warning and deprecations feature
* Fix up docs
* Remove legal_inputs munging from _handle_aliases()
This is done in AnsibleModule by the _set_internal_properties() method. It only makes sense
to do that for an AnsibleModule instance (it should update the parameters before performing
validation) and shouldn't be done by the validator.
Create a private function just for getting legal inputs since that is done in a couple of places.
It may make sense store that on the ValidationResult object.
* Increase test coverage
* Remove unnecessary conditional
ci_complete
* Mark warnings and deprecations as private in the ValidationResult
They can be made public once we come up with a way to make them more generally useful,
probably by creating cusom objects to store the data in more structure way.
* Mark valid_parameter_names as private and populate it during initialization
* Use a global for storing the list of additonal checks to perform
This list is used by the main validate method as well as the sub spec validation.
* module compat for py3.8+ controller
* replaced internal usages of selinux bindings with internal ctypes binding (allows basic selinux operations from any Python interpreter), plus tests
* added new respawn_module API to allow modules to import Python packages that are only available under a well-known interpreter, plus tests
* added respawn logic to modules that need Python libs from a specific system interpreter (apt, apt_repository, dnf, yum)
minimize internal HAVE_SELINUX usage
spurious junk
pep8
* pylint fixes
* add RHEL8 Python 3.8 testing
* more pylint
* import sanity
* unit tests
* changelog update
* fix a bunch of stuff
* tweak changelog
* fix setup_rpm_repo on EL8
* misc sanity/test fixes
* misc feedback tweaks
* fix import fallback in test module
* fix selinux MU test
* fix dnf tests to avoid python-dependent test packages
* add trailing LFs to aliases
* fix yum tests to avoid test package with Python deps
* hack create_repo for EL6 to create noarch package