ansible_core-2.19.0b4/ 0000755 0000000 0000000 00000000000 15010426755 013221 5 ustar 00root root ansible_core-2.19.0b4/COPYING 0000644 0000000 0000000 00000104515 15010426755 014262 0 ustar 00root root GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program 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.
This program 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 this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Copyright (C)
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.
ansible_core-2.19.0b4/MANIFEST.in 0000644 0000000 0000000 00000000544 15010426755 014762 0 ustar 00root root include COPYING
include changelogs/CHANGELOG*.rst
include changelogs/changelog.yaml
include licenses/*.txt
include requirements.txt
recursive-include packaging *.py *.j2
recursive-include test/integration *
recursive-include test/sanity *.in *.json *.py *.txt *.ini
recursive-include test/support *.py *.ps1 *.psm1 *.cs *.md
recursive-include test/units *
ansible_core-2.19.0b4/PKG-INFO 0000644 0000000 0000000 00000017064 15010426755 014326 0 ustar 00root root Metadata-Version: 2.4
Name: ansible-core
Version: 2.19.0b4
Summary: Radically simple IT automation
Author: Ansible Project
Project-URL: Homepage, https://ansible.com/
Project-URL: Source Code, https://github.com/ansible/ansible/
Project-URL: Bug Tracker, https://github.com/ansible/ansible/issues/
Project-URL: CI: Azure Pipelines, https://dev.azure.com/ansible/ansible/
Project-URL: Documentation, https://docs.ansible.com/ansible-core/
Project-URL: Code of Conduct, https://docs.ansible.com/ansible/latest/community/code_of_conduct.html
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
Classifier: Natural Language :: English
Classifier: Operating System :: POSIX
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: System :: Installation/Setup
Classifier: Topic :: System :: Systems Administration
Classifier: Topic :: Utilities
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: COPYING
License-File: licenses/Apache-License.txt
License-File: licenses/BSD-3-Clause.txt
License-File: licenses/MIT-license.txt
License-File: licenses/PSF-license.txt
License-File: licenses/simplified_bsd.txt
Requires-Dist: jinja2>=3.1.0
Requires-Dist: PyYAML>=5.1
Requires-Dist: cryptography
Requires-Dist: packaging
Requires-Dist: resolvelib<2.0.0,>=0.5.3
Dynamic: license-file
[](https://pypi.org/project/ansible-core)
[](https://docs.ansible.com/ansible/latest/)
[](https://docs.ansible.com/ansible/devel/community/communication.html)
[](https://dev.azure.com/ansible/ansible/_build/latest?definitionId=20&branchName=devel)
[](https://docs.ansible.com/ansible/devel/community/code_of_conduct.html)
[](https://docs.ansible.com/ansible/devel/community/communication.html#mailing-list-information)
[](COPYING)
[](https://bestpractices.coreinfrastructure.org/projects/2372)
# Ansible
Ansible is a radically simple IT automation system. It handles
configuration management, application deployment, cloud provisioning,
ad-hoc task execution, network automation, and multi-node orchestration. Ansible makes complex
changes like zero-downtime rolling updates with load balancers easy. More information on the Ansible [website](https://ansible.com/).
## Design Principles
* Have an extremely simple setup process with a minimal learning curve.
* Manage machines quickly and in parallel.
* Avoid custom-agents and additional open ports, be agentless by
leveraging the existing SSH daemon.
* Describe infrastructure in a language that is both machine and human
friendly.
* Focus on security and easy auditability/review/rewriting of content.
* Manage new remote machines instantly, without bootstrapping any
software.
* Allow module development in any dynamic language, not just Python.
* Be usable as non-root.
* Be the easiest IT automation system to use, ever.
## Use Ansible
You can install a released version of Ansible with `pip` or a package manager. See our
[installation guide](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html) for details on installing Ansible
on a variety of platforms.
Power users and developers can run the `devel` branch, which has the latest
features and fixes, directly. Although it is reasonably stable, you are more likely to encounter
breaking changes when running the `devel` branch. We recommend getting involved
in the Ansible community if you want to run the `devel` branch.
## Communication
Join the Ansible forum to ask questions, get help, and interact with the
community.
* [Get Help](https://forum.ansible.com/c/help/6): Find help or share your Ansible knowledge to help others.
Use tags to filter and subscribe to posts, such as the following:
* Posts tagged with [ansible](https://forum.ansible.com/tag/ansible)
* Posts tagged with [ansible-core](https://forum.ansible.com/tag/ansible-core)
* Posts tagged with [playbook](https://forum.ansible.com/tag/playbook)
* [Social Spaces](https://forum.ansible.com/c/chat/4): Meet and interact with fellow enthusiasts.
* [News & Announcements](https://forum.ansible.com/c/news/5): Track project-wide announcements including social events.
* [Bullhorn newsletter](https://docs.ansible.com/ansible/devel/community/communication.html#the-bullhorn): Get release announcements and important changes.
For more ways to get in touch, see [Communicating with the Ansible community](https://docs.ansible.com/ansible/devel/community/communication.html).
## Contribute to Ansible
* Check out the [Contributor's Guide](./.github/CONTRIBUTING.md).
* Read [Community Information](https://docs.ansible.com/ansible/devel/community) for all
kinds of ways to contribute to and interact with the project,
including how to submit bug reports and code to Ansible.
* Submit a proposed code update through a pull request to the `devel` branch.
* Talk to us before making larger changes
to avoid duplicate efforts. This not only helps everyone
know what is going on, but it also helps save time and effort if we decide
some changes are needed.
## Coding Guidelines
We document our Coding Guidelines in the [Developer Guide](https://docs.ansible.com/ansible/devel/dev_guide/). We particularly suggest you review:
* [Contributing your module to Ansible](https://docs.ansible.com/ansible/devel/dev_guide/developing_modules_checklist.html)
* [Conventions, tips, and pitfalls](https://docs.ansible.com/ansible/devel/dev_guide/developing_modules_best_practices.html)
## Branch Info
* The `devel` branch corresponds to the release actively under development.
* The `stable-2.X` branches correspond to stable releases.
* Create a branch based on `devel` and set up a [dev environment](https://docs.ansible.com/ansible/devel/dev_guide/developing_modules_general.html#common-environment-setup) if you want to open a PR.
* See the [Ansible release and maintenance](https://docs.ansible.com/ansible/devel/reference_appendices/release_and_maintenance.html) page for information about active branches.
## Roadmap
Based on team and community feedback, an initial roadmap will be published for a major or minor version (ex: 2.7, 2.8).
The [Ansible Roadmap page](https://docs.ansible.com/ansible/devel/roadmap/) details what is planned and how to influence the roadmap.
## Authors
Ansible was created by [Michael DeHaan](https://github.com/mpdehaan)
and has contributions from over 5000 users (and growing). Thanks everyone!
[Ansible](https://www.ansible.com) is sponsored by [Red Hat, Inc.](https://www.redhat.com)
## License
GNU General Public License v3.0 or later
See [COPYING](COPYING) to see the full text.
ansible_core-2.19.0b4/README.md 0000644 0000000 0000000 00000013452 15010426755 014505 0 ustar 00root root [](https://pypi.org/project/ansible-core)
[](https://docs.ansible.com/ansible/latest/)
[](https://docs.ansible.com/ansible/devel/community/communication.html)
[](https://dev.azure.com/ansible/ansible/_build/latest?definitionId=20&branchName=devel)
[](https://docs.ansible.com/ansible/devel/community/code_of_conduct.html)
[](https://docs.ansible.com/ansible/devel/community/communication.html#mailing-list-information)
[](COPYING)
[](https://bestpractices.coreinfrastructure.org/projects/2372)
# Ansible
Ansible is a radically simple IT automation system. It handles
configuration management, application deployment, cloud provisioning,
ad-hoc task execution, network automation, and multi-node orchestration. Ansible makes complex
changes like zero-downtime rolling updates with load balancers easy. More information on the Ansible [website](https://ansible.com/).
## Design Principles
* Have an extremely simple setup process with a minimal learning curve.
* Manage machines quickly and in parallel.
* Avoid custom-agents and additional open ports, be agentless by
leveraging the existing SSH daemon.
* Describe infrastructure in a language that is both machine and human
friendly.
* Focus on security and easy auditability/review/rewriting of content.
* Manage new remote machines instantly, without bootstrapping any
software.
* Allow module development in any dynamic language, not just Python.
* Be usable as non-root.
* Be the easiest IT automation system to use, ever.
## Use Ansible
You can install a released version of Ansible with `pip` or a package manager. See our
[installation guide](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html) for details on installing Ansible
on a variety of platforms.
Power users and developers can run the `devel` branch, which has the latest
features and fixes, directly. Although it is reasonably stable, you are more likely to encounter
breaking changes when running the `devel` branch. We recommend getting involved
in the Ansible community if you want to run the `devel` branch.
## Communication
Join the Ansible forum to ask questions, get help, and interact with the
community.
* [Get Help](https://forum.ansible.com/c/help/6): Find help or share your Ansible knowledge to help others.
Use tags to filter and subscribe to posts, such as the following:
* Posts tagged with [ansible](https://forum.ansible.com/tag/ansible)
* Posts tagged with [ansible-core](https://forum.ansible.com/tag/ansible-core)
* Posts tagged with [playbook](https://forum.ansible.com/tag/playbook)
* [Social Spaces](https://forum.ansible.com/c/chat/4): Meet and interact with fellow enthusiasts.
* [News & Announcements](https://forum.ansible.com/c/news/5): Track project-wide announcements including social events.
* [Bullhorn newsletter](https://docs.ansible.com/ansible/devel/community/communication.html#the-bullhorn): Get release announcements and important changes.
For more ways to get in touch, see [Communicating with the Ansible community](https://docs.ansible.com/ansible/devel/community/communication.html).
## Contribute to Ansible
* Check out the [Contributor's Guide](./.github/CONTRIBUTING.md).
* Read [Community Information](https://docs.ansible.com/ansible/devel/community) for all
kinds of ways to contribute to and interact with the project,
including how to submit bug reports and code to Ansible.
* Submit a proposed code update through a pull request to the `devel` branch.
* Talk to us before making larger changes
to avoid duplicate efforts. This not only helps everyone
know what is going on, but it also helps save time and effort if we decide
some changes are needed.
## Coding Guidelines
We document our Coding Guidelines in the [Developer Guide](https://docs.ansible.com/ansible/devel/dev_guide/). We particularly suggest you review:
* [Contributing your module to Ansible](https://docs.ansible.com/ansible/devel/dev_guide/developing_modules_checklist.html)
* [Conventions, tips, and pitfalls](https://docs.ansible.com/ansible/devel/dev_guide/developing_modules_best_practices.html)
## Branch Info
* The `devel` branch corresponds to the release actively under development.
* The `stable-2.X` branches correspond to stable releases.
* Create a branch based on `devel` and set up a [dev environment](https://docs.ansible.com/ansible/devel/dev_guide/developing_modules_general.html#common-environment-setup) if you want to open a PR.
* See the [Ansible release and maintenance](https://docs.ansible.com/ansible/devel/reference_appendices/release_and_maintenance.html) page for information about active branches.
## Roadmap
Based on team and community feedback, an initial roadmap will be published for a major or minor version (ex: 2.7, 2.8).
The [Ansible Roadmap page](https://docs.ansible.com/ansible/devel/roadmap/) details what is planned and how to influence the roadmap.
## Authors
Ansible was created by [Michael DeHaan](https://github.com/mpdehaan)
and has contributions from over 5000 users (and growing). Thanks everyone!
[Ansible](https://www.ansible.com) is sponsored by [Red Hat, Inc.](https://www.redhat.com)
## License
GNU General Public License v3.0 or later
See [COPYING](COPYING) to see the full text.
ansible_core-2.19.0b4/ansible_core.egg-info/ 0000755 0000000 0000000 00000000000 15010426755 017340 5 ustar 00root root ansible_core-2.19.0b4/ansible_core.egg-info/PKG-INFO 0000644 0000000 0000000 00000017064 15010426755 020445 0 ustar 00root root Metadata-Version: 2.4
Name: ansible-core
Version: 2.19.0b4
Summary: Radically simple IT automation
Author: Ansible Project
Project-URL: Homepage, https://ansible.com/
Project-URL: Source Code, https://github.com/ansible/ansible/
Project-URL: Bug Tracker, https://github.com/ansible/ansible/issues/
Project-URL: CI: Azure Pipelines, https://dev.azure.com/ansible/ansible/
Project-URL: Documentation, https://docs.ansible.com/ansible-core/
Project-URL: Code of Conduct, https://docs.ansible.com/ansible/latest/community/code_of_conduct.html
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
Classifier: Natural Language :: English
Classifier: Operating System :: POSIX
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: System :: Installation/Setup
Classifier: Topic :: System :: Systems Administration
Classifier: Topic :: Utilities
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: COPYING
License-File: licenses/Apache-License.txt
License-File: licenses/BSD-3-Clause.txt
License-File: licenses/MIT-license.txt
License-File: licenses/PSF-license.txt
License-File: licenses/simplified_bsd.txt
Requires-Dist: jinja2>=3.1.0
Requires-Dist: PyYAML>=5.1
Requires-Dist: cryptography
Requires-Dist: packaging
Requires-Dist: resolvelib<2.0.0,>=0.5.3
Dynamic: license-file
[](https://pypi.org/project/ansible-core)
[](https://docs.ansible.com/ansible/latest/)
[](https://docs.ansible.com/ansible/devel/community/communication.html)
[](https://dev.azure.com/ansible/ansible/_build/latest?definitionId=20&branchName=devel)
[](https://docs.ansible.com/ansible/devel/community/code_of_conduct.html)
[](https://docs.ansible.com/ansible/devel/community/communication.html#mailing-list-information)
[](COPYING)
[](https://bestpractices.coreinfrastructure.org/projects/2372)
# Ansible
Ansible is a radically simple IT automation system. It handles
configuration management, application deployment, cloud provisioning,
ad-hoc task execution, network automation, and multi-node orchestration. Ansible makes complex
changes like zero-downtime rolling updates with load balancers easy. More information on the Ansible [website](https://ansible.com/).
## Design Principles
* Have an extremely simple setup process with a minimal learning curve.
* Manage machines quickly and in parallel.
* Avoid custom-agents and additional open ports, be agentless by
leveraging the existing SSH daemon.
* Describe infrastructure in a language that is both machine and human
friendly.
* Focus on security and easy auditability/review/rewriting of content.
* Manage new remote machines instantly, without bootstrapping any
software.
* Allow module development in any dynamic language, not just Python.
* Be usable as non-root.
* Be the easiest IT automation system to use, ever.
## Use Ansible
You can install a released version of Ansible with `pip` or a package manager. See our
[installation guide](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html) for details on installing Ansible
on a variety of platforms.
Power users and developers can run the `devel` branch, which has the latest
features and fixes, directly. Although it is reasonably stable, you are more likely to encounter
breaking changes when running the `devel` branch. We recommend getting involved
in the Ansible community if you want to run the `devel` branch.
## Communication
Join the Ansible forum to ask questions, get help, and interact with the
community.
* [Get Help](https://forum.ansible.com/c/help/6): Find help or share your Ansible knowledge to help others.
Use tags to filter and subscribe to posts, such as the following:
* Posts tagged with [ansible](https://forum.ansible.com/tag/ansible)
* Posts tagged with [ansible-core](https://forum.ansible.com/tag/ansible-core)
* Posts tagged with [playbook](https://forum.ansible.com/tag/playbook)
* [Social Spaces](https://forum.ansible.com/c/chat/4): Meet and interact with fellow enthusiasts.
* [News & Announcements](https://forum.ansible.com/c/news/5): Track project-wide announcements including social events.
* [Bullhorn newsletter](https://docs.ansible.com/ansible/devel/community/communication.html#the-bullhorn): Get release announcements and important changes.
For more ways to get in touch, see [Communicating with the Ansible community](https://docs.ansible.com/ansible/devel/community/communication.html).
## Contribute to Ansible
* Check out the [Contributor's Guide](./.github/CONTRIBUTING.md).
* Read [Community Information](https://docs.ansible.com/ansible/devel/community) for all
kinds of ways to contribute to and interact with the project,
including how to submit bug reports and code to Ansible.
* Submit a proposed code update through a pull request to the `devel` branch.
* Talk to us before making larger changes
to avoid duplicate efforts. This not only helps everyone
know what is going on, but it also helps save time and effort if we decide
some changes are needed.
## Coding Guidelines
We document our Coding Guidelines in the [Developer Guide](https://docs.ansible.com/ansible/devel/dev_guide/). We particularly suggest you review:
* [Contributing your module to Ansible](https://docs.ansible.com/ansible/devel/dev_guide/developing_modules_checklist.html)
* [Conventions, tips, and pitfalls](https://docs.ansible.com/ansible/devel/dev_guide/developing_modules_best_practices.html)
## Branch Info
* The `devel` branch corresponds to the release actively under development.
* The `stable-2.X` branches correspond to stable releases.
* Create a branch based on `devel` and set up a [dev environment](https://docs.ansible.com/ansible/devel/dev_guide/developing_modules_general.html#common-environment-setup) if you want to open a PR.
* See the [Ansible release and maintenance](https://docs.ansible.com/ansible/devel/reference_appendices/release_and_maintenance.html) page for information about active branches.
## Roadmap
Based on team and community feedback, an initial roadmap will be published for a major or minor version (ex: 2.7, 2.8).
The [Ansible Roadmap page](https://docs.ansible.com/ansible/devel/roadmap/) details what is planned and how to influence the roadmap.
## Authors
Ansible was created by [Michael DeHaan](https://github.com/mpdehaan)
and has contributions from over 5000 users (and growing). Thanks everyone!
[Ansible](https://www.ansible.com) is sponsored by [Red Hat, Inc.](https://www.redhat.com)
## License
GNU General Public License v3.0 or later
See [COPYING](COPYING) to see the full text.
ansible_core-2.19.0b4/ansible_core.egg-info/SOURCES.txt 0000644 0000000 0000000 00001201774 15010426755 021240 0 ustar 00root root COPYING
MANIFEST.in
README.md
pyproject.toml
requirements.txt
ansible_core.egg-info/PKG-INFO
ansible_core.egg-info/SOURCES.txt
ansible_core.egg-info/dependency_links.txt
ansible_core.egg-info/entry_points.txt
ansible_core.egg-info/requires.txt
ansible_core.egg-info/top_level.txt
changelogs/CHANGELOG-v2.19.rst
changelogs/changelog.yaml
lib/ansible/__init__.py
lib/ansible/__main__.py
lib/ansible/constants.py
lib/ansible/context.py
lib/ansible/keyword_desc.yml
lib/ansible/release.py
lib/ansible/_internal/__init__.py
lib/ansible/_internal/_ansiballz.py
lib/ansible/_internal/_collection_proxy.py
lib/ansible/_internal/_locking.py
lib/ansible/_internal/_task.py
lib/ansible/_internal/_testing.py
lib/ansible/_internal/_wrapt.py
lib/ansible/_internal/_datatag/__init__.py
lib/ansible/_internal/_datatag/_tags.py
lib/ansible/_internal/_datatag/_utils.py
lib/ansible/_internal/_datatag/_wrappers.py
lib/ansible/_internal/_errors/__init__.py
lib/ansible/_internal/_errors/_captured.py
lib/ansible/_internal/_errors/_handler.py
lib/ansible/_internal/_errors/_utils.py
lib/ansible/_internal/_json/__init__.py
lib/ansible/_internal/_json/_legacy_encoder.py
lib/ansible/_internal/_json/_profiles/__init__.py
lib/ansible/_internal/_json/_profiles/_cache_persistence.py
lib/ansible/_internal/_json/_profiles/_inventory_legacy.py
lib/ansible/_internal/_json/_profiles/_legacy.py
lib/ansible/_internal/_plugins/__init__.py
lib/ansible/_internal/_plugins/_cache.py
lib/ansible/_internal/_templating/__init__.py
lib/ansible/_internal/_templating/_access.py
lib/ansible/_internal/_templating/_chain_templar.py
lib/ansible/_internal/_templating/_datatag.py
lib/ansible/_internal/_templating/_engine.py
lib/ansible/_internal/_templating/_errors.py
lib/ansible/_internal/_templating/_jinja_bits.py
lib/ansible/_internal/_templating/_jinja_common.py
lib/ansible/_internal/_templating/_jinja_patches.py
lib/ansible/_internal/_templating/_jinja_plugins.py
lib/ansible/_internal/_templating/_lazy_containers.py
lib/ansible/_internal/_templating/_marker_behaviors.py
lib/ansible/_internal/_templating/_transform.py
lib/ansible/_internal/_templating/_utils.py
lib/ansible/_internal/_yaml/__init__.py
lib/ansible/_internal/_yaml/_constructor.py
lib/ansible/_internal/_yaml/_dumper.py
lib/ansible/_internal/_yaml/_errors.py
lib/ansible/_internal/_yaml/_loader.py
lib/ansible/_internal/ansible_collections/ansible/_protomatter/README.md
lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/action/debug.py
lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/apply_trust.py
lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/dump_object.py
lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/finalize.py
lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/origin.py
lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.py
lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.yml
lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/tag_names.py
lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/true_type.py
lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/unmask.py
lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.py
lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.yml
lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.py
lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.yml
lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.py
lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.yml
lib/ansible/_vendor/__init__.py
lib/ansible/cli/__init__.py
lib/ansible/cli/_ssh_askpass.py
lib/ansible/cli/adhoc.py
lib/ansible/cli/config.py
lib/ansible/cli/console.py
lib/ansible/cli/doc.py
lib/ansible/cli/galaxy.py
lib/ansible/cli/inventory.py
lib/ansible/cli/playbook.py
lib/ansible/cli/pull.py
lib/ansible/cli/vault.py
lib/ansible/cli/arguments/__init__.py
lib/ansible/cli/arguments/option_helpers.py
lib/ansible/cli/scripts/__init__.py
lib/ansible/cli/scripts/ansible_connection_cli_stub.py
lib/ansible/collections/__init__.py
lib/ansible/collections/list.py
lib/ansible/compat/__init__.py
lib/ansible/compat/importlib_resources.py
lib/ansible/config/__init__.py
lib/ansible/config/ansible_builtin_runtime.yml
lib/ansible/config/base.yml
lib/ansible/config/manager.py
lib/ansible/errors/__init__.py
lib/ansible/executor/__init__.py
lib/ansible/executor/interpreter_discovery.py
lib/ansible/executor/module_common.py
lib/ansible/executor/play_iterator.py
lib/ansible/executor/playbook_executor.py
lib/ansible/executor/stats.py
lib/ansible/executor/task_executor.py
lib/ansible/executor/task_queue_manager.py
lib/ansible/executor/task_result.py
lib/ansible/executor/discovery/__init__.py
lib/ansible/executor/powershell/__init__.py
lib/ansible/executor/powershell/async_watchdog.ps1
lib/ansible/executor/powershell/async_wrapper.ps1
lib/ansible/executor/powershell/become_wrapper.ps1
lib/ansible/executor/powershell/bootstrap_wrapper.ps1
lib/ansible/executor/powershell/coverage_wrapper.ps1
lib/ansible/executor/powershell/exec_wrapper.ps1
lib/ansible/executor/powershell/module_manifest.py
lib/ansible/executor/powershell/module_wrapper.ps1
lib/ansible/executor/powershell/psrp_fetch_file.ps1
lib/ansible/executor/powershell/psrp_put_file.ps1
lib/ansible/executor/powershell/winrm_fetch_file.ps1
lib/ansible/executor/powershell/winrm_put_file.ps1
lib/ansible/executor/process/__init__.py
lib/ansible/executor/process/worker.py
lib/ansible/galaxy/__init__.py
lib/ansible/galaxy/api.py
lib/ansible/galaxy/role.py
lib/ansible/galaxy/token.py
lib/ansible/galaxy/user_agent.py
lib/ansible/galaxy/collection/__init__.py
lib/ansible/galaxy/collection/concrete_artifact_manager.py
lib/ansible/galaxy/collection/galaxy_api_proxy.py
lib/ansible/galaxy/collection/gpg.py
lib/ansible/galaxy/data/COPYING
lib/ansible/galaxy/data/collections_galaxy_meta.yml
lib/ansible/galaxy/data/apb/Dockerfile.j2
lib/ansible/galaxy/data/apb/Makefile.j2
lib/ansible/galaxy/data/apb/README.md
lib/ansible/galaxy/data/apb/apb.yml.j2
lib/ansible/galaxy/data/apb/defaults/main.yml.j2
lib/ansible/galaxy/data/apb/files/.git_keep
lib/ansible/galaxy/data/apb/handlers/main.yml.j2
lib/ansible/galaxy/data/apb/meta/main.yml.j2
lib/ansible/galaxy/data/apb/playbooks/deprovision.yml.j2
lib/ansible/galaxy/data/apb/playbooks/provision.yml.j2
lib/ansible/galaxy/data/apb/tasks/main.yml.j2
lib/ansible/galaxy/data/apb/templates/.git_keep
lib/ansible/galaxy/data/apb/tests/ansible.cfg
lib/ansible/galaxy/data/apb/tests/inventory
lib/ansible/galaxy/data/apb/tests/test.yml.j2
lib/ansible/galaxy/data/apb/vars/main.yml.j2
lib/ansible/galaxy/data/container/README.md
lib/ansible/galaxy/data/container/defaults/main.yml.j2
lib/ansible/galaxy/data/container/files/.git_keep
lib/ansible/galaxy/data/container/handlers/main.yml.j2
lib/ansible/galaxy/data/container/meta/container.yml.j2
lib/ansible/galaxy/data/container/meta/main.yml.j2
lib/ansible/galaxy/data/container/tasks/main.yml.j2
lib/ansible/galaxy/data/container/templates/.git_keep
lib/ansible/galaxy/data/container/tests/ansible.cfg
lib/ansible/galaxy/data/container/tests/inventory
lib/ansible/galaxy/data/container/tests/test.yml.j2
lib/ansible/galaxy/data/container/vars/main.yml.j2
lib/ansible/galaxy/data/default/collection/README.md.j2
lib/ansible/galaxy/data/default/collection/galaxy.yml.j2
lib/ansible/galaxy/data/default/collection/docs/.git_keep
lib/ansible/galaxy/data/default/collection/meta/runtime.yml
lib/ansible/galaxy/data/default/collection/plugins/README.md.j2
lib/ansible/galaxy/data/default/collection/roles/.git_keep
lib/ansible/galaxy/data/default/role/README.md
lib/ansible/galaxy/data/default/role/defaults/main.yml.j2
lib/ansible/galaxy/data/default/role/files/.git_keep
lib/ansible/galaxy/data/default/role/handlers/main.yml.j2
lib/ansible/galaxy/data/default/role/meta/main.yml.j2
lib/ansible/galaxy/data/default/role/tasks/main.yml.j2
lib/ansible/galaxy/data/default/role/templates/.git_keep
lib/ansible/galaxy/data/default/role/tests/inventory
lib/ansible/galaxy/data/default/role/tests/test.yml.j2
lib/ansible/galaxy/data/default/role/vars/main.yml.j2
lib/ansible/galaxy/data/network/README.md
lib/ansible/galaxy/data/network/cliconf_plugins/example.py.j2
lib/ansible/galaxy/data/network/defaults/main.yml.j2
lib/ansible/galaxy/data/network/files/.git_keep
lib/ansible/galaxy/data/network/library/example_command.py.j2
lib/ansible/galaxy/data/network/library/example_config.py.j2
lib/ansible/galaxy/data/network/library/example_facts.py.j2
lib/ansible/galaxy/data/network/meta/main.yml.j2
lib/ansible/galaxy/data/network/module_utils/example.py.j2
lib/ansible/galaxy/data/network/netconf_plugins/example.py.j2
lib/ansible/galaxy/data/network/tasks/main.yml.j2
lib/ansible/galaxy/data/network/templates/.git_keep
lib/ansible/galaxy/data/network/terminal_plugins/example.py.j2
lib/ansible/galaxy/data/network/tests/inventory
lib/ansible/galaxy/data/network/tests/test.yml.j2
lib/ansible/galaxy/data/network/vars/main.yml.j2
lib/ansible/galaxy/dependency_resolution/__init__.py
lib/ansible/galaxy/dependency_resolution/dataclasses.py
lib/ansible/galaxy/dependency_resolution/errors.py
lib/ansible/galaxy/dependency_resolution/providers.py
lib/ansible/galaxy/dependency_resolution/reporters.py
lib/ansible/galaxy/dependency_resolution/resolvers.py
lib/ansible/galaxy/dependency_resolution/versioning.py
lib/ansible/inventory/__init__.py
lib/ansible/inventory/data.py
lib/ansible/inventory/group.py
lib/ansible/inventory/helpers.py
lib/ansible/inventory/host.py
lib/ansible/inventory/manager.py
lib/ansible/module_utils/__init__.py
lib/ansible/module_utils/_text.py
lib/ansible/module_utils/ansible_release.py
lib/ansible/module_utils/api.py
lib/ansible/module_utils/basic.py
lib/ansible/module_utils/connection.py
lib/ansible/module_utils/datatag.py
lib/ansible/module_utils/errors.py
lib/ansible/module_utils/json_utils.py
lib/ansible/module_utils/service.py
lib/ansible/module_utils/splitter.py
lib/ansible/module_utils/testing.py
lib/ansible/module_utils/urls.py
lib/ansible/module_utils/yumdnf.py
lib/ansible/module_utils/_internal/__init__.py
lib/ansible/module_utils/_internal/_ambient_context.py
lib/ansible/module_utils/_internal/_ansiballz.py
lib/ansible/module_utils/_internal/_dataclass_validation.py
lib/ansible/module_utils/_internal/_debugging.py
lib/ansible/module_utils/_internal/_deprecator.py
lib/ansible/module_utils/_internal/_errors.py
lib/ansible/module_utils/_internal/_plugin_info.py
lib/ansible/module_utils/_internal/_testing.py
lib/ansible/module_utils/_internal/_traceback.py
lib/ansible/module_utils/_internal/_validation.py
lib/ansible/module_utils/_internal/_concurrent/__init__.py
lib/ansible/module_utils/_internal/_concurrent/_daemon_threading.py
lib/ansible/module_utils/_internal/_concurrent/_futures.py
lib/ansible/module_utils/_internal/_datatag/__init__.py
lib/ansible/module_utils/_internal/_datatag/_tags.py
lib/ansible/module_utils/_internal/_json/__init__.py
lib/ansible/module_utils/_internal/_json/_legacy_encoder.py
lib/ansible/module_utils/_internal/_json/_profiles/__init__.py
lib/ansible/module_utils/_internal/_json/_profiles/_fallback_to_str.py
lib/ansible/module_utils/_internal/_json/_profiles/_module_legacy_c2m.py
lib/ansible/module_utils/_internal/_json/_profiles/_module_legacy_m2c.py
lib/ansible/module_utils/_internal/_json/_profiles/_module_modern_c2m.py
lib/ansible/module_utils/_internal/_json/_profiles/_module_modern_m2c.py
lib/ansible/module_utils/_internal/_json/_profiles/_tagless.py
lib/ansible/module_utils/_internal/_patches/__init__.py
lib/ansible/module_utils/_internal/_patches/_dataclass_annotation_patch.py
lib/ansible/module_utils/_internal/_patches/_socket_patch.py
lib/ansible/module_utils/_internal/_patches/_sys_intern_patch.py
lib/ansible/module_utils/common/__init__.py
lib/ansible/module_utils/common/_collections_compat.py
lib/ansible/module_utils/common/_utils.py
lib/ansible/module_utils/common/arg_spec.py
lib/ansible/module_utils/common/collections.py
lib/ansible/module_utils/common/dict_transformations.py
lib/ansible/module_utils/common/file.py
lib/ansible/module_utils/common/json.py
lib/ansible/module_utils/common/locale.py
lib/ansible/module_utils/common/messages.py
lib/ansible/module_utils/common/network.py
lib/ansible/module_utils/common/parameters.py
lib/ansible/module_utils/common/process.py
lib/ansible/module_utils/common/respawn.py
lib/ansible/module_utils/common/sentinel.py
lib/ansible/module_utils/common/sys_info.py
lib/ansible/module_utils/common/validation.py
lib/ansible/module_utils/common/warnings.py
lib/ansible/module_utils/common/yaml.py
lib/ansible/module_utils/common/text/__init__.py
lib/ansible/module_utils/common/text/converters.py
lib/ansible/module_utils/common/text/formatters.py
lib/ansible/module_utils/compat/__init__.py
lib/ansible/module_utils/compat/datetime.py
lib/ansible/module_utils/compat/paramiko.py
lib/ansible/module_utils/compat/selinux.py
lib/ansible/module_utils/compat/typing.py
lib/ansible/module_utils/compat/version.py
lib/ansible/module_utils/csharp/Ansible.AccessToken.cs
lib/ansible/module_utils/csharp/Ansible.Basic.cs
lib/ansible/module_utils/csharp/Ansible.Become.cs
lib/ansible/module_utils/csharp/Ansible.Privilege.cs
lib/ansible/module_utils/csharp/Ansible.Process.cs
lib/ansible/module_utils/csharp/Ansible._Async.cs
lib/ansible/module_utils/csharp/__init__.py
lib/ansible/module_utils/distro/__init__.py
lib/ansible/module_utils/distro/_distro.py
lib/ansible/module_utils/facts/__init__.py
lib/ansible/module_utils/facts/ansible_collector.py
lib/ansible/module_utils/facts/collector.py
lib/ansible/module_utils/facts/compat.py
lib/ansible/module_utils/facts/default_collectors.py
lib/ansible/module_utils/facts/namespace.py
lib/ansible/module_utils/facts/packages.py
lib/ansible/module_utils/facts/sysctl.py
lib/ansible/module_utils/facts/timeout.py
lib/ansible/module_utils/facts/utils.py
lib/ansible/module_utils/facts/hardware/__init__.py
lib/ansible/module_utils/facts/hardware/aix.py
lib/ansible/module_utils/facts/hardware/base.py
lib/ansible/module_utils/facts/hardware/darwin.py
lib/ansible/module_utils/facts/hardware/dragonfly.py
lib/ansible/module_utils/facts/hardware/freebsd.py
lib/ansible/module_utils/facts/hardware/hpux.py
lib/ansible/module_utils/facts/hardware/hurd.py
lib/ansible/module_utils/facts/hardware/linux.py
lib/ansible/module_utils/facts/hardware/netbsd.py
lib/ansible/module_utils/facts/hardware/openbsd.py
lib/ansible/module_utils/facts/hardware/sunos.py
lib/ansible/module_utils/facts/network/__init__.py
lib/ansible/module_utils/facts/network/aix.py
lib/ansible/module_utils/facts/network/base.py
lib/ansible/module_utils/facts/network/darwin.py
lib/ansible/module_utils/facts/network/dragonfly.py
lib/ansible/module_utils/facts/network/fc_wwn.py
lib/ansible/module_utils/facts/network/freebsd.py
lib/ansible/module_utils/facts/network/generic_bsd.py
lib/ansible/module_utils/facts/network/hpux.py
lib/ansible/module_utils/facts/network/hurd.py
lib/ansible/module_utils/facts/network/iscsi.py
lib/ansible/module_utils/facts/network/linux.py
lib/ansible/module_utils/facts/network/netbsd.py
lib/ansible/module_utils/facts/network/nvme.py
lib/ansible/module_utils/facts/network/openbsd.py
lib/ansible/module_utils/facts/network/sunos.py
lib/ansible/module_utils/facts/other/__init__.py
lib/ansible/module_utils/facts/other/facter.py
lib/ansible/module_utils/facts/other/ohai.py
lib/ansible/module_utils/facts/system/__init__.py
lib/ansible/module_utils/facts/system/apparmor.py
lib/ansible/module_utils/facts/system/caps.py
lib/ansible/module_utils/facts/system/chroot.py
lib/ansible/module_utils/facts/system/cmdline.py
lib/ansible/module_utils/facts/system/date_time.py
lib/ansible/module_utils/facts/system/distribution.py
lib/ansible/module_utils/facts/system/dns.py
lib/ansible/module_utils/facts/system/env.py
lib/ansible/module_utils/facts/system/fips.py
lib/ansible/module_utils/facts/system/loadavg.py
lib/ansible/module_utils/facts/system/local.py
lib/ansible/module_utils/facts/system/lsb.py
lib/ansible/module_utils/facts/system/pkg_mgr.py
lib/ansible/module_utils/facts/system/platform.py
lib/ansible/module_utils/facts/system/python.py
lib/ansible/module_utils/facts/system/selinux.py
lib/ansible/module_utils/facts/system/service_mgr.py
lib/ansible/module_utils/facts/system/ssh_pub_keys.py
lib/ansible/module_utils/facts/system/systemd.py
lib/ansible/module_utils/facts/system/user.py
lib/ansible/module_utils/facts/virtual/__init__.py
lib/ansible/module_utils/facts/virtual/base.py
lib/ansible/module_utils/facts/virtual/dragonfly.py
lib/ansible/module_utils/facts/virtual/freebsd.py
lib/ansible/module_utils/facts/virtual/hpux.py
lib/ansible/module_utils/facts/virtual/linux.py
lib/ansible/module_utils/facts/virtual/netbsd.py
lib/ansible/module_utils/facts/virtual/openbsd.py
lib/ansible/module_utils/facts/virtual/sunos.py
lib/ansible/module_utils/facts/virtual/sysctl.py
lib/ansible/module_utils/parsing/__init__.py
lib/ansible/module_utils/parsing/convert_bool.py
lib/ansible/module_utils/powershell/Ansible.ModuleUtils.AddType.psm1
lib/ansible/module_utils/powershell/Ansible.ModuleUtils.ArgvParser.psm1
lib/ansible/module_utils/powershell/Ansible.ModuleUtils.Backup.psm1
lib/ansible/module_utils/powershell/Ansible.ModuleUtils.CamelConversion.psm1
lib/ansible/module_utils/powershell/Ansible.ModuleUtils.CommandUtil.psm1
lib/ansible/module_utils/powershell/Ansible.ModuleUtils.FileUtil.psm1
lib/ansible/module_utils/powershell/Ansible.ModuleUtils.Legacy.psm1
lib/ansible/module_utils/powershell/Ansible.ModuleUtils.LinkUtil.psm1
lib/ansible/module_utils/powershell/Ansible.ModuleUtils.PrivilegeUtil.psm1
lib/ansible/module_utils/powershell/Ansible.ModuleUtils.SID.psm1
lib/ansible/module_utils/powershell/Ansible.ModuleUtils.WebRequest.psm1
lib/ansible/module_utils/powershell/__init__.py
lib/ansible/module_utils/six/__init__.py
lib/ansible/modules/__init__.py
lib/ansible/modules/add_host.py
lib/ansible/modules/apt.py
lib/ansible/modules/apt_key.py
lib/ansible/modules/apt_repository.py
lib/ansible/modules/assemble.py
lib/ansible/modules/assert.py
lib/ansible/modules/async_status.py
lib/ansible/modules/async_wrapper.py
lib/ansible/modules/blockinfile.py
lib/ansible/modules/command.py
lib/ansible/modules/copy.py
lib/ansible/modules/cron.py
lib/ansible/modules/deb822_repository.py
lib/ansible/modules/debconf.py
lib/ansible/modules/debug.py
lib/ansible/modules/dnf.py
lib/ansible/modules/dnf5.py
lib/ansible/modules/dpkg_selections.py
lib/ansible/modules/expect.py
lib/ansible/modules/fail.py
lib/ansible/modules/fetch.py
lib/ansible/modules/file.py
lib/ansible/modules/find.py
lib/ansible/modules/gather_facts.py
lib/ansible/modules/get_url.py
lib/ansible/modules/getent.py
lib/ansible/modules/git.py
lib/ansible/modules/group.py
lib/ansible/modules/group_by.py
lib/ansible/modules/hostname.py
lib/ansible/modules/import_playbook.py
lib/ansible/modules/import_role.py
lib/ansible/modules/import_tasks.py
lib/ansible/modules/include_role.py
lib/ansible/modules/include_tasks.py
lib/ansible/modules/include_vars.py
lib/ansible/modules/iptables.py
lib/ansible/modules/known_hosts.py
lib/ansible/modules/lineinfile.py
lib/ansible/modules/meta.py
lib/ansible/modules/mount_facts.py
lib/ansible/modules/package.py
lib/ansible/modules/package_facts.py
lib/ansible/modules/pause.py
lib/ansible/modules/ping.py
lib/ansible/modules/pip.py
lib/ansible/modules/raw.py
lib/ansible/modules/reboot.py
lib/ansible/modules/replace.py
lib/ansible/modules/rpm_key.py
lib/ansible/modules/script.py
lib/ansible/modules/service.py
lib/ansible/modules/service_facts.py
lib/ansible/modules/set_fact.py
lib/ansible/modules/set_stats.py
lib/ansible/modules/setup.py
lib/ansible/modules/shell.py
lib/ansible/modules/slurp.py
lib/ansible/modules/stat.py
lib/ansible/modules/subversion.py
lib/ansible/modules/systemd.py
lib/ansible/modules/systemd_service.py
lib/ansible/modules/sysvinit.py
lib/ansible/modules/tempfile.py
lib/ansible/modules/template.py
lib/ansible/modules/unarchive.py
lib/ansible/modules/uri.py
lib/ansible/modules/user.py
lib/ansible/modules/validate_argument_spec.py
lib/ansible/modules/wait_for.py
lib/ansible/modules/wait_for_connection.py
lib/ansible/modules/yum_repository.py
lib/ansible/parsing/__init__.py
lib/ansible/parsing/ajson.py
lib/ansible/parsing/dataloader.py
lib/ansible/parsing/mod_args.py
lib/ansible/parsing/plugin_docs.py
lib/ansible/parsing/quoting.py
lib/ansible/parsing/splitter.py
lib/ansible/parsing/utils/__init__.py
lib/ansible/parsing/utils/addresses.py
lib/ansible/parsing/utils/jsonify.py
lib/ansible/parsing/utils/yaml.py
lib/ansible/parsing/vault/__init__.py
lib/ansible/parsing/yaml/__init__.py
lib/ansible/parsing/yaml/dumper.py
lib/ansible/parsing/yaml/loader.py
lib/ansible/parsing/yaml/objects.py
lib/ansible/playbook/__init__.py
lib/ansible/playbook/attribute.py
lib/ansible/playbook/base.py
lib/ansible/playbook/block.py
lib/ansible/playbook/collectionsearch.py
lib/ansible/playbook/conditional.py
lib/ansible/playbook/delegatable.py
lib/ansible/playbook/handler.py
lib/ansible/playbook/handler_task_include.py
lib/ansible/playbook/helpers.py
lib/ansible/playbook/included_file.py
lib/ansible/playbook/loop_control.py
lib/ansible/playbook/notifiable.py
lib/ansible/playbook/play.py
lib/ansible/playbook/play_context.py
lib/ansible/playbook/playbook_include.py
lib/ansible/playbook/role_include.py
lib/ansible/playbook/taggable.py
lib/ansible/playbook/task.py
lib/ansible/playbook/task_include.py
lib/ansible/playbook/role/__init__.py
lib/ansible/playbook/role/definition.py
lib/ansible/playbook/role/include.py
lib/ansible/playbook/role/metadata.py
lib/ansible/playbook/role/requirement.py
lib/ansible/plugins/__init__.py
lib/ansible/plugins/list.py
lib/ansible/plugins/loader.py
lib/ansible/plugins/action/__init__.py
lib/ansible/plugins/action/add_host.py
lib/ansible/plugins/action/assemble.py
lib/ansible/plugins/action/assert.py
lib/ansible/plugins/action/async_status.py
lib/ansible/plugins/action/command.py
lib/ansible/plugins/action/copy.py
lib/ansible/plugins/action/debug.py
lib/ansible/plugins/action/dnf.py
lib/ansible/plugins/action/fail.py
lib/ansible/plugins/action/fetch.py
lib/ansible/plugins/action/gather_facts.py
lib/ansible/plugins/action/group_by.py
lib/ansible/plugins/action/include_vars.py
lib/ansible/plugins/action/normal.py
lib/ansible/plugins/action/package.py
lib/ansible/plugins/action/pause.py
lib/ansible/plugins/action/raw.py
lib/ansible/plugins/action/reboot.py
lib/ansible/plugins/action/script.py
lib/ansible/plugins/action/service.py
lib/ansible/plugins/action/set_fact.py
lib/ansible/plugins/action/set_stats.py
lib/ansible/plugins/action/shell.py
lib/ansible/plugins/action/template.py
lib/ansible/plugins/action/unarchive.py
lib/ansible/plugins/action/uri.py
lib/ansible/plugins/action/validate_argument_spec.py
lib/ansible/plugins/action/wait_for_connection.py
lib/ansible/plugins/become/__init__.py
lib/ansible/plugins/become/runas.py
lib/ansible/plugins/become/su.py
lib/ansible/plugins/become/sudo.py
lib/ansible/plugins/cache/__init__.py
lib/ansible/plugins/cache/base.py
lib/ansible/plugins/cache/jsonfile.py
lib/ansible/plugins/cache/memory.py
lib/ansible/plugins/callback/__init__.py
lib/ansible/plugins/callback/default.py
lib/ansible/plugins/callback/junit.py
lib/ansible/plugins/callback/minimal.py
lib/ansible/plugins/callback/oneline.py
lib/ansible/plugins/callback/tree.py
lib/ansible/plugins/cliconf/__init__.py
lib/ansible/plugins/connection/__init__.py
lib/ansible/plugins/connection/local.py
lib/ansible/plugins/connection/paramiko_ssh.py
lib/ansible/plugins/connection/psrp.py
lib/ansible/plugins/connection/ssh.py
lib/ansible/plugins/connection/winrm.py
lib/ansible/plugins/doc_fragments/__init__.py
lib/ansible/plugins/doc_fragments/action_common_attributes.py
lib/ansible/plugins/doc_fragments/action_core.py
lib/ansible/plugins/doc_fragments/backup.py
lib/ansible/plugins/doc_fragments/checksum_common.py
lib/ansible/plugins/doc_fragments/connection_pipelining.py
lib/ansible/plugins/doc_fragments/constructed.py
lib/ansible/plugins/doc_fragments/decrypt.py
lib/ansible/plugins/doc_fragments/default_callback.py
lib/ansible/plugins/doc_fragments/files.py
lib/ansible/plugins/doc_fragments/inventory_cache.py
lib/ansible/plugins/doc_fragments/result_format_callback.py
lib/ansible/plugins/doc_fragments/return_common.py
lib/ansible/plugins/doc_fragments/shell_common.py
lib/ansible/plugins/doc_fragments/shell_windows.py
lib/ansible/plugins/doc_fragments/template_common.py
lib/ansible/plugins/doc_fragments/url.py
lib/ansible/plugins/doc_fragments/url_windows.py
lib/ansible/plugins/doc_fragments/validate.py
lib/ansible/plugins/doc_fragments/vars_plugin_staging.py
lib/ansible/plugins/filter/__init__.py
lib/ansible/plugins/filter/b64decode.yml
lib/ansible/plugins/filter/b64encode.yml
lib/ansible/plugins/filter/basename.yml
lib/ansible/plugins/filter/bool.yml
lib/ansible/plugins/filter/checksum.yml
lib/ansible/plugins/filter/combinations.yml
lib/ansible/plugins/filter/combine.yml
lib/ansible/plugins/filter/comment.yml
lib/ansible/plugins/filter/commonpath.yml
lib/ansible/plugins/filter/core.py
lib/ansible/plugins/filter/dict2items.yml
lib/ansible/plugins/filter/difference.yml
lib/ansible/plugins/filter/dirname.yml
lib/ansible/plugins/filter/encryption.py
lib/ansible/plugins/filter/expanduser.yml
lib/ansible/plugins/filter/expandvars.yml
lib/ansible/plugins/filter/extract.yml
lib/ansible/plugins/filter/fileglob.yml
lib/ansible/plugins/filter/flatten.yml
lib/ansible/plugins/filter/from_json.yml
lib/ansible/plugins/filter/from_yaml.yml
lib/ansible/plugins/filter/from_yaml_all.yml
lib/ansible/plugins/filter/hash.yml
lib/ansible/plugins/filter/human_readable.yml
lib/ansible/plugins/filter/human_to_bytes.yml
lib/ansible/plugins/filter/intersect.yml
lib/ansible/plugins/filter/items2dict.yml
lib/ansible/plugins/filter/log.yml
lib/ansible/plugins/filter/mandatory.yml
lib/ansible/plugins/filter/mathstuff.py
lib/ansible/plugins/filter/md5.yml
lib/ansible/plugins/filter/normpath.yml
lib/ansible/plugins/filter/password_hash.yml
lib/ansible/plugins/filter/path_join.yml
lib/ansible/plugins/filter/permutations.yml
lib/ansible/plugins/filter/pow.yml
lib/ansible/plugins/filter/product.yml
lib/ansible/plugins/filter/quote.yml
lib/ansible/plugins/filter/random.yml
lib/ansible/plugins/filter/realpath.yml
lib/ansible/plugins/filter/regex_escape.yml
lib/ansible/plugins/filter/regex_findall.yml
lib/ansible/plugins/filter/regex_replace.yml
lib/ansible/plugins/filter/regex_search.yml
lib/ansible/plugins/filter/rekey_on_member.yml
lib/ansible/plugins/filter/relpath.yml
lib/ansible/plugins/filter/root.yml
lib/ansible/plugins/filter/sha1.yml
lib/ansible/plugins/filter/shuffle.yml
lib/ansible/plugins/filter/split.yml
lib/ansible/plugins/filter/splitext.yml
lib/ansible/plugins/filter/strftime.yml
lib/ansible/plugins/filter/subelements.yml
lib/ansible/plugins/filter/symmetric_difference.yml
lib/ansible/plugins/filter/ternary.yml
lib/ansible/plugins/filter/to_datetime.yml
lib/ansible/plugins/filter/to_json.yml
lib/ansible/plugins/filter/to_nice_json.yml
lib/ansible/plugins/filter/to_nice_yaml.yml
lib/ansible/plugins/filter/to_uuid.yml
lib/ansible/plugins/filter/to_yaml.yml
lib/ansible/plugins/filter/type_debug.yml
lib/ansible/plugins/filter/union.yml
lib/ansible/plugins/filter/unique.yml
lib/ansible/plugins/filter/unvault.yml
lib/ansible/plugins/filter/urldecode.yml
lib/ansible/plugins/filter/urls.py
lib/ansible/plugins/filter/urlsplit.py
lib/ansible/plugins/filter/vault.yml
lib/ansible/plugins/filter/win_basename.yml
lib/ansible/plugins/filter/win_dirname.yml
lib/ansible/plugins/filter/win_splitdrive.yml
lib/ansible/plugins/filter/zip.yml
lib/ansible/plugins/filter/zip_longest.yml
lib/ansible/plugins/httpapi/__init__.py
lib/ansible/plugins/inventory/__init__.py
lib/ansible/plugins/inventory/advanced_host_list.py
lib/ansible/plugins/inventory/auto.py
lib/ansible/plugins/inventory/constructed.py
lib/ansible/plugins/inventory/generator.py
lib/ansible/plugins/inventory/host_list.py
lib/ansible/plugins/inventory/ini.py
lib/ansible/plugins/inventory/script.py
lib/ansible/plugins/inventory/toml.py
lib/ansible/plugins/inventory/yaml.py
lib/ansible/plugins/lookup/__init__.py
lib/ansible/plugins/lookup/config.py
lib/ansible/plugins/lookup/csvfile.py
lib/ansible/plugins/lookup/dict.py
lib/ansible/plugins/lookup/env.py
lib/ansible/plugins/lookup/file.py
lib/ansible/plugins/lookup/fileglob.py
lib/ansible/plugins/lookup/first_found.py
lib/ansible/plugins/lookup/indexed_items.py
lib/ansible/plugins/lookup/ini.py
lib/ansible/plugins/lookup/inventory_hostnames.py
lib/ansible/plugins/lookup/items.py
lib/ansible/plugins/lookup/lines.py
lib/ansible/plugins/lookup/list.py
lib/ansible/plugins/lookup/nested.py
lib/ansible/plugins/lookup/password.py
lib/ansible/plugins/lookup/pipe.py
lib/ansible/plugins/lookup/random_choice.py
lib/ansible/plugins/lookup/sequence.py
lib/ansible/plugins/lookup/subelements.py
lib/ansible/plugins/lookup/template.py
lib/ansible/plugins/lookup/together.py
lib/ansible/plugins/lookup/unvault.py
lib/ansible/plugins/lookup/url.py
lib/ansible/plugins/lookup/varnames.py
lib/ansible/plugins/lookup/vars.py
lib/ansible/plugins/netconf/__init__.py
lib/ansible/plugins/shell/__init__.py
lib/ansible/plugins/shell/cmd.py
lib/ansible/plugins/shell/powershell.py
lib/ansible/plugins/shell/sh.py
lib/ansible/plugins/strategy/__init__.py
lib/ansible/plugins/strategy/debug.py
lib/ansible/plugins/strategy/free.py
lib/ansible/plugins/strategy/host_pinned.py
lib/ansible/plugins/strategy/linear.py
lib/ansible/plugins/terminal/__init__.py
lib/ansible/plugins/test/__init__.py
lib/ansible/plugins/test/abs.yml
lib/ansible/plugins/test/all.yml
lib/ansible/plugins/test/any.yml
lib/ansible/plugins/test/change.yml
lib/ansible/plugins/test/changed.yml
lib/ansible/plugins/test/contains.yml
lib/ansible/plugins/test/core.py
lib/ansible/plugins/test/directory.yml
lib/ansible/plugins/test/exists.yml
lib/ansible/plugins/test/failed.yml
lib/ansible/plugins/test/failure.yml
lib/ansible/plugins/test/falsy.yml
lib/ansible/plugins/test/file.yml
lib/ansible/plugins/test/files.py
lib/ansible/plugins/test/finished.yml
lib/ansible/plugins/test/is_abs.yml
lib/ansible/plugins/test/is_dir.yml
lib/ansible/plugins/test/is_file.yml
lib/ansible/plugins/test/is_link.yml
lib/ansible/plugins/test/is_mount.yml
lib/ansible/plugins/test/is_same_file.yml
lib/ansible/plugins/test/isnan.yml
lib/ansible/plugins/test/issubset.yml
lib/ansible/plugins/test/issuperset.yml
lib/ansible/plugins/test/link.yml
lib/ansible/plugins/test/link_exists.yml
lib/ansible/plugins/test/match.yml
lib/ansible/plugins/test/mathstuff.py
lib/ansible/plugins/test/mount.yml
lib/ansible/plugins/test/nan.yml
lib/ansible/plugins/test/reachable.yml
lib/ansible/plugins/test/regex.yml
lib/ansible/plugins/test/same_file.yml
lib/ansible/plugins/test/search.yml
lib/ansible/plugins/test/skip.yml
lib/ansible/plugins/test/skipped.yml
lib/ansible/plugins/test/started.yml
lib/ansible/plugins/test/subset.yml
lib/ansible/plugins/test/succeeded.yml
lib/ansible/plugins/test/success.yml
lib/ansible/plugins/test/successful.yml
lib/ansible/plugins/test/superset.yml
lib/ansible/plugins/test/timedout.yml
lib/ansible/plugins/test/truthy.yml
lib/ansible/plugins/test/unreachable.yml
lib/ansible/plugins/test/uri.py
lib/ansible/plugins/test/uri.yml
lib/ansible/plugins/test/url.yml
lib/ansible/plugins/test/urn.yml
lib/ansible/plugins/test/vault_encrypted.yml
lib/ansible/plugins/test/vaulted_file.yml
lib/ansible/plugins/test/version.yml
lib/ansible/plugins/test/version_compare.yml
lib/ansible/plugins/vars/__init__.py
lib/ansible/plugins/vars/host_group_vars.py
lib/ansible/template/__init__.py
lib/ansible/utils/__init__.py
lib/ansible/utils/_junit_xml.py
lib/ansible/utils/_ssh_agent.py
lib/ansible/utils/cmd_functions.py
lib/ansible/utils/color.py
lib/ansible/utils/context_objects.py
lib/ansible/utils/display.py
lib/ansible/utils/encrypt.py
lib/ansible/utils/fqcn.py
lib/ansible/utils/galaxy.py
lib/ansible/utils/hashing.py
lib/ansible/utils/helpers.py
lib/ansible/utils/jsonrpc.py
lib/ansible/utils/listify.py
lib/ansible/utils/lock.py
lib/ansible/utils/multiprocessing.py
lib/ansible/utils/path.py
lib/ansible/utils/plugin_docs.py
lib/ansible/utils/py3compat.py
lib/ansible/utils/sentinel.py
lib/ansible/utils/shlex.py
lib/ansible/utils/singleton.py
lib/ansible/utils/ssh_functions.py
lib/ansible/utils/unicode.py
lib/ansible/utils/unsafe_proxy.py
lib/ansible/utils/vars.py
lib/ansible/utils/version.py
lib/ansible/utils/collection_loader/__init__.py
lib/ansible/utils/collection_loader/_collection_config.py
lib/ansible/utils/collection_loader/_collection_finder.py
lib/ansible/utils/collection_loader/_collection_meta.py
lib/ansible/vars/__init__.py
lib/ansible/vars/clean.py
lib/ansible/vars/hostvars.py
lib/ansible/vars/manager.py
lib/ansible/vars/plugins.py
lib/ansible/vars/reserved.py
licenses/Apache-License.txt
licenses/BSD-3-Clause.txt
licenses/MIT-license.txt
licenses/PSF-license.txt
licenses/simplified_bsd.txt
packaging/release.py
packaging/cli-doc/build.py
packaging/cli-doc/man.j2
packaging/cli-doc/rst.j2
test/integration/network-integration.cfg
test/integration/network-integration.requirements.txt
test/integration/targets/add_host/aliases
test/integration/targets/add_host/tasks/main.yml
test/integration/targets/adhoc/aliases
test/integration/targets/adhoc/runme.sh
test/integration/targets/ansiballz_debug/aliases
test/integration/targets/ansiballz_debug/tasks/main.yml
test/integration/targets/ansiballz_python/aliases
test/integration/targets/ansiballz_python/library/check_rlimit_and_maxfd.py
test/integration/targets/ansiballz_python/library/custom_module.py
test/integration/targets/ansiballz_python/library/sys_check.py
test/integration/targets/ansiballz_python/module_utils/custom_util.py
test/integration/targets/ansiballz_python/tasks/main.yml
test/integration/targets/ansible/adhoc-callback.stdout
test/integration/targets/ansible/aliases
test/integration/targets/ansible/ansible-testé.cfg
test/integration/targets/ansible/module_common_regex_regression.sh
test/integration/targets/ansible/no-extension
test/integration/targets/ansible/playbook.yml
test/integration/targets/ansible/playbookdir_cfg.ini
test/integration/targets/ansible/runme.sh
test/integration/targets/ansible/vars.yml
test/integration/targets/ansible-config/aliases
test/integration/targets/ansible-config/files/base_all_valid.cfg
test/integration/targets/ansible-config/files/base_valid.cfg
test/integration/targets/ansible-config/files/empty.cfg
test/integration/targets/ansible-config/files/galaxy_server.ini
test/integration/targets/ansible-config/files/ini_dupes.py
test/integration/targets/ansible-config/files/invalid_base.cfg
test/integration/targets/ansible-config/files/invalid_plugins_config.ini
test/integration/targets/ansible-config/tasks/main.yml
test/integration/targets/ansible-console/aliases
test/integration/targets/ansible-console/runme.sh
test/integration/targets/ansible-doc/aliases
test/integration/targets/ansible-doc/fakecollrole.output
test/integration/targets/ansible-doc/fakemodule.output
test/integration/targets/ansible-doc/fakerole.output
test/integration/targets/ansible-doc/fix-urls.py
test/integration/targets/ansible-doc/inventory
test/integration/targets/ansible-doc/noop.output
test/integration/targets/ansible-doc/noop_vars_plugin.output
test/integration/targets/ansible-doc/notjsonfile.output
test/integration/targets/ansible-doc/randommodule-text-verbose.output
test/integration/targets/ansible-doc/randommodule-text.output
test/integration/targets/ansible-doc/randommodule.output
test/integration/targets/ansible-doc/runme.sh
test/integration/targets/ansible-doc/test.yml
test/integration/targets/ansible-doc/test_docs_returns.output
test/integration/targets/ansible-doc/test_docs_suboptions.output
test/integration/targets/ansible-doc/test_docs_yaml_anchors.output
test/integration/targets/ansible-doc/yolo-text.output
test/integration/targets/ansible-doc/yolo.output
test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/MANIFEST.json
test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/cache/notjsonfile.py
test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/inventory/statichost.py
test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/lookup/noop.py
test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/modules/fakemodule.py
test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/modules/notrealmodule.py
test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/modules/randommodule.py
test/integration/targets/ansible-doc/broken-docs/collections/ansible_collections/testns/testcol/plugins/vars/noop_vars_plugin.py
test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/MANIFEST.json
test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/cache/notjsonfile.py
test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/filter/grouped.py
test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/filter/ultimatequestion.yml
test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/filter/filter_subdir/in_subdir.py
test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/inventory/statichost.py
test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/lookup/noop.py
test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/fakemodule.py
test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/notrealmodule.py
test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/randommodule.py
test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/modules/database/database_type/subdir_module.py
test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/test/test_test.py
test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/test/yolo.yml
test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/plugins/vars/noop_vars_plugin.py
test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/roles/testrole/meta/main.yml
test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol/roles/testrole_with_no_argspecs/meta/empty
test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/MANIFEST.json
test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/deprecation.py
test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/module.py
test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/plugin.py
test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol2/plugins/doc_fragments/version_added.py
test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol3/galaxy.yml
test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol3/plugins/modules/test1.py
test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol4/galaxy.yml
test/integration/targets/ansible-doc/collections/ansible_collections/testns/testcol4/plugins/modules/test2.py
test/integration/targets/ansible-doc/filter_plugins/donothing.yml
test/integration/targets/ansible-doc/filter_plugins/other.py
test/integration/targets/ansible-doc/filter_plugins/split.yml
test/integration/targets/ansible-doc/library/double_doc.py
test/integration/targets/ansible-doc/library/test_docs.py
test/integration/targets/ansible-doc/library/test_docs_missing_description.py
test/integration/targets/ansible-doc/library/test_docs_no_metadata.py
test/integration/targets/ansible-doc/library/test_docs_no_status.py
test/integration/targets/ansible-doc/library/test_docs_non_iterable_status.py
test/integration/targets/ansible-doc/library/test_docs_removed_precedence.py
test/integration/targets/ansible-doc/library/test_docs_removed_status.py
test/integration/targets/ansible-doc/library/test_docs_returns.py
test/integration/targets/ansible-doc/library/test_docs_returns_broken.py
test/integration/targets/ansible-doc/library/test_docs_suboptions.py
test/integration/targets/ansible-doc/library/test_docs_yaml_anchors.py
test/integration/targets/ansible-doc/library/test_empty.py
test/integration/targets/ansible-doc/library/test_no_docs.py
test/integration/targets/ansible-doc/library/test_no_docs_no_metadata.py
test/integration/targets/ansible-doc/library/test_no_docs_no_status.py
test/integration/targets/ansible-doc/library/test_no_docs_non_iterable_status.py
test/integration/targets/ansible-doc/library/test_win_module.ps1
test/integration/targets/ansible-doc/library/test_win_module.yml
test/integration/targets/ansible-doc/lookup_plugins/_deprecated_with_adj_docs.py
test/integration/targets/ansible-doc/lookup_plugins/_deprecated_with_docs.py
test/integration/targets/ansible-doc/lookup_plugins/broken_docs.py
test/integration/targets/ansible-doc/lookup_plugins/deprecated_with_adj_docs.yml
test/integration/targets/ansible-doc/roles/test_role1/meta/argument_specs.yml
test/integration/targets/ansible-doc/roles/test_role1/meta/main.yml
test/integration/targets/ansible-doc/roles/test_role2/meta/empty
test/integration/targets/ansible-doc/roles/test_role3/meta/main.yml
test/integration/targets/ansible-doc/test_role1/README.txt
test/integration/targets/ansible-doc/test_role1/meta/main.yml
test/integration/targets/ansible-galaxy/aliases
test/integration/targets/ansible-galaxy/cleanup-default.yml
test/integration/targets/ansible-galaxy/cleanup-freebsd.yml
test/integration/targets/ansible-galaxy/cleanup.yml
test/integration/targets/ansible-galaxy/runme.sh
test/integration/targets/ansible-galaxy/setup.yml
test/integration/targets/ansible-galaxy-collection/aliases
test/integration/targets/ansible-galaxy-collection-cli/aliases
test/integration/targets/ansible-galaxy-collection-cli/files/empty_manifest_galaxy.yml
test/integration/targets/ansible-galaxy-collection-cli/files/expected.txt
test/integration/targets/ansible-galaxy-collection-cli/files/expected_empty.txt
test/integration/targets/ansible-galaxy-collection-cli/files/expected_full_manifest.txt
test/integration/targets/ansible-galaxy-collection-cli/files/full_manifest_galaxy.yml
test/integration/targets/ansible-galaxy-collection-cli/files/galaxy.yml
test/integration/targets/ansible-galaxy-collection-cli/files/make_collection_dir.py
test/integration/targets/ansible-galaxy-collection-cli/tasks/main.yml
test/integration/targets/ansible-galaxy-collection-cli/tasks/manifest.yml
test/integration/targets/ansible-galaxy-collection-scm/aliases
test/integration/targets/ansible-galaxy-collection-scm/meta/main.yml
test/integration/targets/ansible-galaxy-collection-scm/tasks/download.yml
test/integration/targets/ansible-galaxy-collection-scm/tasks/empty_installed_collections.yml
test/integration/targets/ansible-galaxy-collection-scm/tasks/individual_collection_repo.yml
test/integration/targets/ansible-galaxy-collection-scm/tasks/main.yml
test/integration/targets/ansible-galaxy-collection-scm/tasks/multi_collection_repo_all.yml
test/integration/targets/ansible-galaxy-collection-scm/tasks/multi_collection_repo_individual.yml
test/integration/targets/ansible-galaxy-collection-scm/tasks/reinstalling.yml
test/integration/targets/ansible-galaxy-collection-scm/tasks/requirements.yml
test/integration/targets/ansible-galaxy-collection-scm/tasks/scm_dependency.yml
test/integration/targets/ansible-galaxy-collection-scm/tasks/scm_dependency_deduplication.yml
test/integration/targets/ansible-galaxy-collection-scm/tasks/setup.yml
test/integration/targets/ansible-galaxy-collection-scm/tasks/setup_collection_bad_version.yml
test/integration/targets/ansible-galaxy-collection-scm/tasks/setup_multi_collection_repo.yml
test/integration/targets/ansible-galaxy-collection-scm/tasks/setup_recursive_scm_dependency.yml
test/integration/targets/ansible-galaxy-collection-scm/tasks/test_invalid_version.yml
test/integration/targets/ansible-galaxy-collection-scm/tasks/test_manifest_metadata.yml
test/integration/targets/ansible-galaxy-collection-scm/tasks/test_supported_resolvelib_versions.yml
test/integration/targets/ansible-galaxy-collection-scm/templates/git_prefix_name.yml
test/integration/targets/ansible-galaxy-collection-scm/templates/name_and_type.yml
test/integration/targets/ansible-galaxy-collection-scm/templates/name_without_type.yml
test/integration/targets/ansible-galaxy-collection-scm/templates/source_and_name.yml
test/integration/targets/ansible-galaxy-collection-scm/templates/source_and_name_and_type.yml
test/integration/targets/ansible-galaxy-collection-scm/templates/source_only.yml
test/integration/targets/ansible-galaxy-collection-scm/vars/main.yml
test/integration/targets/ansible-galaxy-collection/files/build_bad_tar.py
test/integration/targets/ansible-galaxy-collection/files/test_module.py
test/integration/targets/ansible-galaxy-collection/handlers/main.yml
test/integration/targets/ansible-galaxy-collection/library/reset_pulp.py
test/integration/targets/ansible-galaxy-collection/library/setup_collections.py
test/integration/targets/ansible-galaxy-collection/meta/main.yml
test/integration/targets/ansible-galaxy-collection/tasks/build.yml
test/integration/targets/ansible-galaxy-collection/tasks/download.yml
test/integration/targets/ansible-galaxy-collection/tasks/fail_fast_resolvelib.yml
test/integration/targets/ansible-galaxy-collection/tasks/init.yml
test/integration/targets/ansible-galaxy-collection/tasks/install.yml
test/integration/targets/ansible-galaxy-collection/tasks/install_offline.yml
test/integration/targets/ansible-galaxy-collection/tasks/list.yml
test/integration/targets/ansible-galaxy-collection/tasks/main.yml
test/integration/targets/ansible-galaxy-collection/tasks/pinned_pre_releases_in_deptree.yml
test/integration/targets/ansible-galaxy-collection/tasks/publish.yml
test/integration/targets/ansible-galaxy-collection/tasks/pulp.yml
test/integration/targets/ansible-galaxy-collection/tasks/revoke_gpg_key.yml
test/integration/targets/ansible-galaxy-collection/tasks/setup_gpg.yml
test/integration/targets/ansible-galaxy-collection/tasks/supported_resolvelib.yml
test/integration/targets/ansible-galaxy-collection/tasks/unsupported_resolvelib.yml
test/integration/targets/ansible-galaxy-collection/tasks/upgrade.yml
test/integration/targets/ansible-galaxy-collection/tasks/verify.yml
test/integration/targets/ansible-galaxy-collection/tasks/virtual_direct_requests.yml
test/integration/targets/ansible-galaxy-collection/templates/ansible.cfg.j2
test/integration/targets/ansible-galaxy-collection/vars/main.yml
test/integration/targets/ansible-galaxy-role/aliases
test/integration/targets/ansible-galaxy-role/files/create-role-archive.py
test/integration/targets/ansible-galaxy-role/files/safe-symlinks/defaults/main.yml
test/integration/targets/ansible-galaxy-role/files/safe-symlinks/defaults/common_vars/subdir/group0/main.yml
test/integration/targets/ansible-galaxy-role/files/safe-symlinks/handlers/utils.yml
test/integration/targets/ansible-galaxy-role/files/safe-symlinks/meta/main.yml
test/integration/targets/ansible-galaxy-role/files/safe-symlinks/tasks/utils/suite.yml
test/integration/targets/ansible-galaxy-role/meta/main.yml
test/integration/targets/ansible-galaxy-role/tasks/dir-traversal.yml
test/integration/targets/ansible-galaxy-role/tasks/main.yml
test/integration/targets/ansible-galaxy-role/tasks/valid-role-symlinks.yml
test/integration/targets/ansible-galaxy/files/testserver.py
test/integration/targets/ansible-inventory/aliases
test/integration/targets/ansible-inventory/post_inventory.yml
test/integration/targets/ansible-inventory/runme.sh
test/integration/targets/ansible-inventory/test.yml
test/integration/targets/ansible-inventory/with_untrusted.yml
test/integration/targets/ansible-inventory/with_untrusted_expected.json
test/integration/targets/ansible-inventory/files/complex.ini
test/integration/targets/ansible-inventory/files/unicode.yml
test/integration/targets/ansible-inventory/files/valid_sample.toml
test/integration/targets/ansible-inventory/files/valid_sample.yml
test/integration/targets/ansible-inventory/filter_plugins/toml.py
test/integration/targets/ansible-inventory/tasks/json_output.yml
test/integration/targets/ansible-inventory/tasks/main.yml
test/integration/targets/ansible-inventory/tasks/toml.yml
test/integration/targets/ansible-inventory/tasks/toml_output.yml
test/integration/targets/ansible-inventory/tasks/yaml_output.yml
test/integration/targets/ansible-playbook-callbacks/aliases
test/integration/targets/ansible-playbook-callbacks/all-callbacks.yml
test/integration/targets/ansible-playbook-callbacks/callback_list_include_role_fail.expected
test/integration/targets/ansible-playbook-callbacks/callbacks_list.expected
test/integration/targets/ansible-playbook-callbacks/include_me.yml
test/integration/targets/ansible-playbook-callbacks/include_role-fail.yml
test/integration/targets/ansible-playbook-callbacks/runme.sh
test/integration/targets/ansible-pull/aliases
test/integration/targets/ansible-pull/cleanup.yml
test/integration/targets/ansible-pull/runme.sh
test/integration/targets/ansible-pull/setup.yml
test/integration/targets/ansible-pull/pull-integration-test/ansible.cfg
test/integration/targets/ansible-pull/pull-integration-test/conn_secret.yml
test/integration/targets/ansible-pull/pull-integration-test/gather_facts.yml
test/integration/targets/ansible-pull/pull-integration-test/inventory
test/integration/targets/ansible-pull/pull-integration-test/local.yml
test/integration/targets/ansible-pull/pull-integration-test/multi_play_1.yml
test/integration/targets/ansible-pull/pull-integration-test/multi_play_2.yml
test/integration/targets/ansible-pull/pull-integration-test/secret_connection_password
test/integration/targets/ansible-pull/pull-integration-test/test_empty_facts.yml
test/integration/targets/ansible-test/aliases
test/integration/targets/ansible-test/venv-pythons.py
test/integration/targets/ansible-test-cloud-acme/aliases
test/integration/targets/ansible-test-cloud-acme/tasks/main.yml
test/integration/targets/ansible-test-cloud-aws/aliases
test/integration/targets/ansible-test-cloud-aws/tasks/main.yml
test/integration/targets/ansible-test-cloud-azure/aliases
test/integration/targets/ansible-test-cloud-azure/tasks/main.yml
test/integration/targets/ansible-test-cloud-cs/aliases
test/integration/targets/ansible-test-cloud-cs/tasks/main.yml
test/integration/targets/ansible-test-cloud-galaxy/aliases
test/integration/targets/ansible-test-cloud-galaxy/tasks/main.yml
test/integration/targets/ansible-test-cloud-httptester/aliases
test/integration/targets/ansible-test-cloud-httptester-windows/aliases
test/integration/targets/ansible-test-cloud-httptester-windows/tasks/main.yml
test/integration/targets/ansible-test-cloud-httptester/tasks/main.yml
test/integration/targets/ansible-test-cloud-nios/aliases
test/integration/targets/ansible-test-cloud-nios/tasks/main.yml
test/integration/targets/ansible-test-cloud-openshift/aliases
test/integration/targets/ansible-test-cloud-openshift/tasks/main.yml
test/integration/targets/ansible-test-config/aliases
test/integration/targets/ansible-test-config/runme.sh
test/integration/targets/ansible-test-config-invalid/aliases
test/integration/targets/ansible-test-config-invalid/runme.sh
test/integration/targets/ansible-test-config-invalid/ansible_collections/ns/col/tests/config.yml
test/integration/targets/ansible-test-config-invalid/ansible_collections/ns/col/tests/integration/targets/test/aliases
test/integration/targets/ansible-test-config-invalid/ansible_collections/ns/col/tests/integration/targets/test/runme.sh
test/integration/targets/ansible-test-config-invalid/ansible_collections/ns/col/tests/unit/plugins/module_utils/test_test.py
test/integration/targets/ansible-test-config/ansible_collections/ns/col/plugins/module_utils/test.py
test/integration/targets/ansible-test-config/ansible_collections/ns/col/tests/config.yml
test/integration/targets/ansible-test-config/ansible_collections/ns/col/tests/unit/plugins/module_utils/test_test.py
test/integration/targets/ansible-test-container/aliases
test/integration/targets/ansible-test-container/runme.py
test/integration/targets/ansible-test-container/runme.sh
test/integration/targets/ansible-test-coverage/aliases
test/integration/targets/ansible-test-coverage/runme.sh
test/integration/targets/ansible-test-coverage-windows/aliases
test/integration/targets/ansible-test-coverage-windows/runme.sh
test/integration/targets/ansible-test-coverage-windows/test-coverage.py
test/integration/targets/ansible-test-coverage-windows/ansible_collections/ns/col/plugins/module_utils/CollectionPwshCoverage.psm1
test/integration/targets/ansible-test-coverage-windows/ansible_collections/ns/col/plugins/modules/win_collection.ps1
test/integration/targets/ansible-test-coverage-windows/ansible_collections/ns/col/tests/integration/targets/win_collection/library/test_win_collection_async.ps1
test/integration/targets/ansible-test-coverage-windows/ansible_collections/ns/col/tests/integration/targets/win_collection/library/test_win_collection_become.ps1
test/integration/targets/ansible-test-coverage-windows/ansible_collections/ns/col/tests/integration/targets/win_collection/library/test_win_collection_normal.ps1
test/integration/targets/ansible-test-coverage-windows/ansible_collections/ns/col/tests/integration/targets/win_collection/module_utils/Ansible.ModuleUtils.AdjacentPwshCoverage.psm1
test/integration/targets/ansible-test-coverage-windows/ansible_collections/ns/col/tests/integration/targets/win_collection/tasks/main.yml
test/integration/targets/ansible-test-coverage/ansible_collections/ns/col/plugins/module_utils/test_util.py
test/integration/targets/ansible-test-docker/aliases
test/integration/targets/ansible-test-docker/runme.sh
test/integration/targets/ansible-test-docker/ansible_collections/ns/col/galaxy.yml
test/integration/targets/ansible-test-docker/ansible_collections/ns/col/plugins/doc_fragments/ps_util.py
test/integration/targets/ansible-test-docker/ansible_collections/ns/col/plugins/module_utils/PSUtil.psm1
test/integration/targets/ansible-test-docker/ansible_collections/ns/col/plugins/module_utils/my_util.py
test/integration/targets/ansible-test-docker/ansible_collections/ns/col/plugins/modules/hello.py
test/integration/targets/ansible-test-docker/ansible_collections/ns/col/plugins/modules/win_util_args.ps1
test/integration/targets/ansible-test-docker/ansible_collections/ns/col/plugins/modules/win_util_args.py
test/integration/targets/ansible-test-docker/ansible_collections/ns/col/tests/integration/targets/minimal/aliases
test/integration/targets/ansible-test-docker/ansible_collections/ns/col/tests/integration/targets/minimal/tasks/main.yml
test/integration/targets/ansible-test-docker/ansible_collections/ns/col/tests/unit/plugins/module_utils/test_my_util.py
test/integration/targets/ansible-test-docker/ansible_collections/ns/col/tests/unit/plugins/modules/test_hello.py
test/integration/targets/ansible-test-git/aliases
test/integration/targets/ansible-test-git/runme.sh
test/integration/targets/ansible-test-git/ansible_collections/ns/col/tests/.keep
test/integration/targets/ansible-test-git/collection-tests/git-at-collection-base.sh
test/integration/targets/ansible-test-git/collection-tests/git-at-collection-root.sh
test/integration/targets/ansible-test-git/collection-tests/git-common.bash
test/integration/targets/ansible-test-git/collection-tests/install-git.yml
test/integration/targets/ansible-test-git/collection-tests/uninstall-git.yml
test/integration/targets/ansible-test-installed/aliases
test/integration/targets/ansible-test-installed/runme.sh
test/integration/targets/ansible-test-installed/ansible_collections/ns/col/tests/integration/targets/installed/aliases
test/integration/targets/ansible-test-installed/ansible_collections/ns/col/tests/integration/targets/installed/runme.sh
test/integration/targets/ansible-test-integration/aliases
test/integration/targets/ansible-test-integration/runme.sh
test/integration/targets/ansible-test-integration-constraints/aliases
test/integration/targets/ansible-test-integration-constraints/runme.sh
test/integration/targets/ansible-test-integration-constraints/ansible_collections/ns/col/tests/integration/constraints.txt
test/integration/targets/ansible-test-integration-constraints/ansible_collections/ns/col/tests/integration/requirements.txt
test/integration/targets/ansible-test-integration-constraints/ansible_collections/ns/col/tests/integration/targets/constraints/aliases
test/integration/targets/ansible-test-integration-constraints/ansible_collections/ns/col/tests/integration/targets/constraints/tasks/main.yml
test/integration/targets/ansible-test-integration-no-exec-script/aliases
test/integration/targets/ansible-test-integration-no-exec-script/runme.sh
test/integration/targets/ansible-test-integration-no-exec-script/ansible_collections/ns/col/tests/integration/targets/hello/aliases
test/integration/targets/ansible-test-integration-no-exec-script/ansible_collections/ns/col/tests/integration/targets/hello/runme.sh
test/integration/targets/ansible-test-integration-targets/aliases
test/integration/targets/ansible-test-integration-targets/runme.sh
test/integration/targets/ansible-test-integration-targets/test.py
test/integration/targets/ansible-test-integration-targets/ansible_collections/ns/col/tests/integration/target-prefixes.something
test/integration/targets/ansible-test-integration-targets/ansible_collections/ns/col/tests/integration/targets/destructive_a/aliases
test/integration/targets/ansible-test-integration-targets/ansible_collections/ns/col/tests/integration/targets/destructive_b/aliases
test/integration/targets/ansible-test-integration-targets/ansible_collections/ns/col/tests/integration/targets/disabled_a/aliases
test/integration/targets/ansible-test-integration-targets/ansible_collections/ns/col/tests/integration/targets/disabled_b/aliases
test/integration/targets/ansible-test-integration-targets/ansible_collections/ns/col/tests/integration/targets/one-part_test/aliases
test/integration/targets/ansible-test-integration-targets/ansible_collections/ns/col/tests/integration/targets/two_part_test/aliases
test/integration/targets/ansible-test-integration-targets/ansible_collections/ns/col/tests/integration/targets/unstable_a/aliases
test/integration/targets/ansible-test-integration-targets/ansible_collections/ns/col/tests/integration/targets/unstable_b/aliases
test/integration/targets/ansible-test-integration-targets/ansible_collections/ns/col/tests/integration/targets/unsupported_a/aliases
test/integration/targets/ansible-test-integration-targets/ansible_collections/ns/col/tests/integration/targets/unsupported_b/aliases
test/integration/targets/ansible-test-integration/ansible_collections/ns/col/plugins/module_utils/my_util.py
test/integration/targets/ansible-test-integration/ansible_collections/ns/col/plugins/modules/hello.py
test/integration/targets/ansible-test-integration/ansible_collections/ns/col/tests/integration/targets/hello/aliases
test/integration/targets/ansible-test-integration/ansible_collections/ns/col/tests/integration/targets/hello/tasks/main.yml
test/integration/targets/ansible-test-no-tty/aliases
test/integration/targets/ansible-test-no-tty/runme.sh
test/integration/targets/ansible-test-no-tty/ansible_collections/ns/col/run-with-pty.py
test/integration/targets/ansible-test-no-tty/ansible_collections/ns/col/vendored_pty.py
test/integration/targets/ansible-test-no-tty/ansible_collections/ns/col/tests/integration/targets/no-tty/aliases
test/integration/targets/ansible-test-no-tty/ansible_collections/ns/col/tests/integration/targets/no-tty/assert-no-tty.py
test/integration/targets/ansible-test-no-tty/ansible_collections/ns/col/tests/integration/targets/no-tty/runme.sh
test/integration/targets/ansible-test-sanity/aliases
test/integration/targets/ansible-test-sanity/runme.sh
test/integration/targets/ansible-test-sanity-action-plugin-docs/aliases
test/integration/targets/ansible-test-sanity-action-plugin-docs/runme.sh
test/integration/targets/ansible-test-sanity-action-plugin-docs/ansible_collections/ns/col/plugins/action/other.yml
test/integration/targets/ansible-test-sanity-action-plugin-docs/ansible_collections/ns/col/plugins/action/with_py.py
test/integration/targets/ansible-test-sanity-action-plugin-docs/ansible_collections/ns/col/plugins/action/with_yaml.py
test/integration/targets/ansible-test-sanity-action-plugin-docs/ansible_collections/ns/col/plugins/action/with_yml.py
test/integration/targets/ansible-test-sanity-action-plugin-docs/ansible_collections/ns/col/plugins/modules/with_py.py
test/integration/targets/ansible-test-sanity-action-plugin-docs/ansible_collections/ns/col/plugins/modules/with_yaml.yaml
test/integration/targets/ansible-test-sanity-action-plugin-docs/ansible_collections/ns/col/plugins/modules/with_yml.yml
test/integration/targets/ansible-test-sanity-ansible-doc/aliases
test/integration/targets/ansible-test-sanity-ansible-doc/runme.sh
test/integration/targets/ansible-test-sanity-ansible-doc/ansible_collections/ns/col/plugins/lookup/lookup1.py
test/integration/targets/ansible-test-sanity-ansible-doc/ansible_collections/ns/col/plugins/lookup/a/b/lookup2.py
test/integration/targets/ansible-test-sanity-ansible-doc/ansible_collections/ns/col/plugins/modules/_module3.py
test/integration/targets/ansible-test-sanity-ansible-doc/ansible_collections/ns/col/plugins/modules/module1.py
test/integration/targets/ansible-test-sanity-ansible-doc/ansible_collections/ns/col/plugins/modules/a/b/module2.py
test/integration/targets/ansible-test-sanity-import/aliases
test/integration/targets/ansible-test-sanity-import/expected.txt
test/integration/targets/ansible-test-sanity-import/runme.sh
test/integration/targets/ansible-test-sanity-import/ansible_collections/ns/col/plugins/lookup/vendor1.py
test/integration/targets/ansible-test-sanity-import/ansible_collections/ns/col/plugins/lookup/vendor2.py
test/integration/targets/ansible-test-sanity-lint/aliases
test/integration/targets/ansible-test-sanity-lint/expected.txt
test/integration/targets/ansible-test-sanity-lint/runme.sh
test/integration/targets/ansible-test-sanity-no-get-exception/aliases
test/integration/targets/ansible-test-sanity-no-get-exception/expected.txt
test/integration/targets/ansible-test-sanity-no-get-exception/runme.sh
test/integration/targets/ansible-test-sanity-no-get-exception/ansible_collections/ns/col/do-not-check-me.py
test/integration/targets/ansible-test-sanity-no-get-exception/ansible_collections/ns/col/plugins/modules/check-me.py
test/integration/targets/ansible-test-sanity-pylint/aliases
test/integration/targets/ansible-test-sanity-pylint/deprecated_thing.py
test/integration/targets/ansible-test-sanity-pylint/expected.txt
test/integration/targets/ansible-test-sanity-pylint/runme.sh
test/integration/targets/ansible-test-sanity-pylint/ansible_collections/ns/col/galaxy.yml
test/integration/targets/ansible-test-sanity-pylint/ansible_collections/ns/col/plugins/action/do_deprecated_stuff.py
test/integration/targets/ansible-test-sanity-pylint/ansible_collections/ns/col/plugins/lookup/deprecated.py
test/integration/targets/ansible-test-sanity-pylint/ansible_collections/ns/col/plugins/module_utils/deprecated_utils.py
test/integration/targets/ansible-test-sanity-replace-urlopen/aliases
test/integration/targets/ansible-test-sanity-replace-urlopen/expected.txt
test/integration/targets/ansible-test-sanity-replace-urlopen/runme.sh
test/integration/targets/ansible-test-sanity-replace-urlopen/ansible_collections/ns/col/do-not-check-me.py
test/integration/targets/ansible-test-sanity-replace-urlopen/ansible_collections/ns/col/plugins/modules/check-me.py
test/integration/targets/ansible-test-sanity-runtime-metadata/aliases
test/integration/targets/ansible-test-sanity-runtime-metadata/expected-no_version.txt
test/integration/targets/ansible-test-sanity-runtime-metadata/expected-version.txt
test/integration/targets/ansible-test-sanity-runtime-metadata/runme.sh
test/integration/targets/ansible-test-sanity-runtime-metadata/ansible_collections/ns/no_version/galaxy.yml
test/integration/targets/ansible-test-sanity-runtime-metadata/ansible_collections/ns/no_version/meta/runtime.yml
test/integration/targets/ansible-test-sanity-runtime-metadata/ansible_collections/ns/version/galaxy.yml
test/integration/targets/ansible-test-sanity-runtime-metadata/ansible_collections/ns/version/meta/runtime.yml
test/integration/targets/ansible-test-sanity-shebang/aliases
test/integration/targets/ansible-test-sanity-shebang/expected.txt
test/integration/targets/ansible-test-sanity-shebang/runme.sh
test/integration/targets/ansible-test-sanity-shebang/ansible_collections/ns/col/plugins/modules/powershell.ps1
test/integration/targets/ansible-test-sanity-shebang/ansible_collections/ns/col/plugins/modules/python-no-shebang.py
test/integration/targets/ansible-test-sanity-shebang/ansible_collections/ns/col/plugins/modules/python.py
test/integration/targets/ansible-test-sanity-shebang/ansible_collections/ns/col/scripts/env_bash.sh
test/integration/targets/ansible-test-sanity-shebang/ansible_collections/ns/col/scripts/env_python.py
test/integration/targets/ansible-test-sanity-shebang/ansible_collections/ns/col/scripts/sh.sh
test/integration/targets/ansible-test-sanity-shebang/ansible_collections/ns/col/tests/integration/targets/valid/env_bash.sh
test/integration/targets/ansible-test-sanity-shebang/ansible_collections/ns/col/tests/integration/targets/valid/env_python.py
test/integration/targets/ansible-test-sanity-shebang/ansible_collections/ns/col/tests/integration/targets/valid/sh.sh
test/integration/targets/ansible-test-sanity-use-compat-six/aliases
test/integration/targets/ansible-test-sanity-use-compat-six/expected.txt
test/integration/targets/ansible-test-sanity-use-compat-six/runme.sh
test/integration/targets/ansible-test-sanity-use-compat-six/ansible_collections/ns/col/do-not-check-me.py
test/integration/targets/ansible-test-sanity-use-compat-six/ansible_collections/ns/col/plugins/modules/check-me.py
test/integration/targets/ansible-test-sanity-validate-modules/aliases
test/integration/targets/ansible-test-sanity-validate-modules/expected.txt
test/integration/targets/ansible-test-sanity-validate-modules/runme.sh
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/meta/runtime.yml
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/lookup/import_order_lookup.py
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/_not_deprecated.py
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_1.py
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_2.py
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_3.py
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_4.py
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_5.py
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_6.py
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/check_mode_attribute_7.py
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/import_order.py
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/invalid_argument_spec_extra_key.py
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/invalid_argument_spec_incorrect_context.py
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/invalid_choice_value.py
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/invalid_yaml_syntax.py
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/no_callable.py
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/option_name_casing.py
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/semantic_markup.py
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/sidecar.py
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/sidecar.yaml
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/unsupported_extension.nope
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/valid_argument_spec_context.py
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/col/plugins/modules/wrong_aliases.py
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/failure/README.md
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/failure/galaxy.yml
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/failure/meta/main.yml
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/failure/meta/runtime.yml
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/failure/plugins/modules/failure_ps.ps1
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/failure/plugins/modules/failure_ps.yml
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/ps_only/README.md
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/ps_only/galaxy.yml
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/ps_only/meta/runtime.yml
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/ps_only/plugins/module_utils/share_module.psm1
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/ps_only/plugins/module_utils/validate.psm1
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/ps_only/plugins/modules/in_function.ps1
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/ps_only/plugins/modules/in_function.yml
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/ps_only/plugins/modules/sidecar.ps1
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/ps_only/plugins/modules/sidecar.yml
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/ps_only/plugins/modules/util_ansible_requires.ps1
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/ps_only/plugins/modules/util_ansible_requires.yml
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/ps_only/plugins/modules/util_optional.ps1
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/ps_only/plugins/modules/util_optional.yml
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/ps_only/plugins/modules/validate.ps1
test/integration/targets/ansible-test-sanity-validate-modules/ansible_collections/ns/ps_only/plugins/modules/validate.py
test/integration/targets/ansible-test-sanity-yamllint/aliases
test/integration/targets/ansible-test-sanity-yamllint/expected.txt
test/integration/targets/ansible-test-sanity-yamllint/runme.sh
test/integration/targets/ansible-test-sanity-yamllint/ansible_collections/ns/col/plugins/inventory/inventory1.py
test/integration/targets/ansible-test-sanity-yamllint/ansible_collections/ns/col/plugins/modules/module1.py
test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/README.md
test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/galaxy.yml
test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/meta/runtime.yml
test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/lookup/bad.py
test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/lookup/world.py
test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/module_utils/__init__.py
test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/modules/bad.py
test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/plugin_utils/check_pylint.py
test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/plugins/random_directory/bad.py
test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/tests/integration/targets/hello/files/bad.py
test/integration/targets/ansible-test-sanity/ansible_collections/ns/col/tests/sanity/ignore.txt
test/integration/targets/ansible-test-shell/aliases
test/integration/targets/ansible-test-shell/expected-stderr.txt
test/integration/targets/ansible-test-shell/expected-stdout.txt
test/integration/targets/ansible-test-shell/runme.sh
test/integration/targets/ansible-test-shell/ansible_collections/ns/col/.keep
test/integration/targets/ansible-test-units/aliases
test/integration/targets/ansible-test-units/runme.sh
test/integration/targets/ansible-test-units-assertions/aliases
test/integration/targets/ansible-test-units-assertions/runme.sh
test/integration/targets/ansible-test-units-assertions/ansible_collections/ns/col/tests/unit/plugins/modules/test_assertion.py
test/integration/targets/ansible-test-units-constraints/aliases
test/integration/targets/ansible-test-units-constraints/runme.sh
test/integration/targets/ansible-test-units-constraints/ansible_collections/ns/col/tests/unit/constraints.txt
test/integration/targets/ansible-test-units-constraints/ansible_collections/ns/col/tests/unit/requirements.txt
test/integration/targets/ansible-test-units-constraints/ansible_collections/ns/col/tests/unit/plugins/modules/test_constraints.py
test/integration/targets/ansible-test-units-forked/aliases
test/integration/targets/ansible-test-units-forked/runme.sh
test/integration/targets/ansible-test-units-forked/ansible_collections/ns/col/tests/unit/plugins/modules/test_ansible_forked.py
test/integration/targets/ansible-test-units/ansible_collections/ns/col/plugins/module_utils/my_util.py
test/integration/targets/ansible-test-units/ansible_collections/ns/col/plugins/modules/hello.py
test/integration/targets/ansible-test-units/ansible_collections/ns/col/tests/unit/plugins/module_utils/test_my_util.py
test/integration/targets/ansible-test-units/ansible_collections/ns/col/tests/unit/plugins/modules/test_hello.py
test/integration/targets/ansible-test-unsupported-directory/aliases
test/integration/targets/ansible-test-unsupported-directory/runme.sh
test/integration/targets/ansible-test-unsupported-directory/ansible_collections/ns/col/.keep
test/integration/targets/ansible-test-vendoring/aliases
test/integration/targets/ansible-test-vendoring/runme.sh
test/integration/targets/ansible-test-vendoring/ansible_collections/ns/col/tests/config.yml
test/integration/targets/ansible-vault/aliases
test/integration/targets/ansible-vault/empty-password
test/integration/targets/ansible-vault/encrypted-vault-password
test/integration/targets/ansible-vault/encrypted_file_encrypted_var_password
test/integration/targets/ansible-vault/example1_password
test/integration/targets/ansible-vault/example2_password
test/integration/targets/ansible-vault/example3_password
test/integration/targets/ansible-vault/faux-editor.py
test/integration/targets/ansible-vault/format_1_1_AES256.yml
test/integration/targets/ansible-vault/format_1_2_AES256.yml
test/integration/targets/ansible-vault/inventory.toml
test/integration/targets/ansible-vault/password-script.py
test/integration/targets/ansible-vault/realpath.yml
test/integration/targets/ansible-vault/runme.sh
test/integration/targets/ansible-vault/single_vault_as_string.yml
test/integration/targets/ansible-vault/symlink.yml
test/integration/targets/ansible-vault/test-vault-client.py
test/integration/targets/ansible-vault/test_dangling_temp.yml
test/integration/targets/ansible-vault/test_utf8_value_in_filename.yml
test/integration/targets/ansible-vault/test_vault.yml
test/integration/targets/ansible-vault/test_vault_embedded.yml
test/integration/targets/ansible-vault/test_vault_embedded_ids.yml
test/integration/targets/ansible-vault/test_vault_file_encrypted_embedded.yml
test/integration/targets/ansible-vault/test_vaulted_inventory.yml
test/integration/targets/ansible-vault/test_vaulted_inventory_toml.yml
test/integration/targets/ansible-vault/test_vaulted_template.yml
test/integration/targets/ansible-vault/test_vaulted_utf8_value.yml
test/integration/targets/ansible-vault/vault-café.yml
test/integration/targets/ansible-vault/vault-password
test/integration/targets/ansible-vault/vault-password-ansible
test/integration/targets/ansible-vault/vault-password-wrong
test/integration/targets/ansible-vault/vault-secret.txt
test/integration/targets/ansible-vault/vaulted.inventory
test/integration/targets/ansible-vault/files/test_assemble/nonsecret.txt
test/integration/targets/ansible-vault/files/test_assemble/secret.vault
test/integration/targets/ansible-vault/host_vars/myhost.yml
test/integration/targets/ansible-vault/host_vars/testhost.yml
test/integration/targets/ansible-vault/invalid_format/README.md
test/integration/targets/ansible-vault/invalid_format/broken-group-vars-tasks.yml
test/integration/targets/ansible-vault/invalid_format/broken-host-vars-tasks.yml
test/integration/targets/ansible-vault/invalid_format/inventory
test/integration/targets/ansible-vault/invalid_format/original-broken-host-vars
test/integration/targets/ansible-vault/invalid_format/original-group-vars.yml
test/integration/targets/ansible-vault/invalid_format/some-vars
test/integration/targets/ansible-vault/invalid_format/vault-secret
test/integration/targets/ansible-vault/invalid_format/group_vars/broken-group-vars.yml
test/integration/targets/ansible-vault/invalid_format/host_vars/broken-host-vars.example.com/vars
test/integration/targets/ansible-vault/roles/test_vault/tasks/main.yml
test/integration/targets/ansible-vault/roles/test_vault/vars/main.yml
test/integration/targets/ansible-vault/roles/test_vault_embedded/tasks/main.yml
test/integration/targets/ansible-vault/roles/test_vault_embedded/vars/main.yml
test/integration/targets/ansible-vault/roles/test_vault_embedded_ids/tasks/main.yml
test/integration/targets/ansible-vault/roles/test_vault_embedded_ids/vars/main.yml
test/integration/targets/ansible-vault/roles/test_vault_file_encrypted_embedded/README.md
test/integration/targets/ansible-vault/roles/test_vault_file_encrypted_embedded/tasks/main.yml
test/integration/targets/ansible-vault/roles/test_vault_file_encrypted_embedded/vars/main.yml
test/integration/targets/ansible-vault/roles/test_vaulted_template/tasks/main.yml
test/integration/targets/ansible-vault/roles/test_vaulted_template/templates/vaulted_template.j2
test/integration/targets/ansible-vault/script/vault-secret.sh
test/integration/targets/ansible-vault/symlink/get-password-symlink
test/integration/targets/ansible-vault/vars/vaulted.yml
test/integration/targets/ansible/callback_plugins/callback_meta.py
test/integration/targets/ansible_log/aliases
test/integration/targets/ansible_log/logit.yml
test/integration/targets/ansible_log/runme.sh
test/integration/targets/any_errors_fatal/31543.yml
test/integration/targets/any_errors_fatal/36308.yml
test/integration/targets/any_errors_fatal/50897.yml
test/integration/targets/any_errors_fatal/73246.yml
test/integration/targets/any_errors_fatal/80981.yml
test/integration/targets/any_errors_fatal/aliases
test/integration/targets/any_errors_fatal/always_block.yml
test/integration/targets/any_errors_fatal/inventory
test/integration/targets/any_errors_fatal/on_includes.yml
test/integration/targets/any_errors_fatal/play_level.yml
test/integration/targets/any_errors_fatal/runme.sh
test/integration/targets/any_errors_fatal/test_fatal.yml
test/integration/targets/apt/aliases
test/integration/targets/apt/defaults/main.yml
test/integration/targets/apt/handlers/main.yml
test/integration/targets/apt/meta/main.yml
test/integration/targets/apt/tasks/apt-builddep.yml
test/integration/targets/apt/tasks/apt-multiarch.yml
test/integration/targets/apt/tasks/apt.yml
test/integration/targets/apt/tasks/downgrade.yml
test/integration/targets/apt/tasks/main.yml
test/integration/targets/apt/tasks/repo.yml
test/integration/targets/apt/tasks/upgrade.yml
test/integration/targets/apt/tasks/upgrade_autoremove.yml
test/integration/targets/apt/tasks/upgrade_scenarios.yml
test/integration/targets/apt/tasks/url-with-deps.yml
test/integration/targets/apt/vars/Ubuntu-20.yml
test/integration/targets/apt/vars/Ubuntu-22.yml
test/integration/targets/apt/vars/Ubuntu-24.yml
test/integration/targets/apt/vars/default.yml
test/integration/targets/apt/vars/arch/amd64.yml
test/integration/targets/apt/vars/arch/arm64.yml
test/integration/targets/apt_key/aliases
test/integration/targets/apt_key/meta/main.yml
test/integration/targets/apt_key/tasks/apt_key.yml
test/integration/targets/apt_key/tasks/apt_key_binary.yml
test/integration/targets/apt_key/tasks/apt_key_inline_data.yml
test/integration/targets/apt_key/tasks/file.yml
test/integration/targets/apt_key/tasks/main.yml
test/integration/targets/apt_repository/aliases
test/integration/targets/apt_repository/tasks/apt.yml
test/integration/targets/apt_repository/tasks/cleanup.yml
test/integration/targets/apt_repository/tasks/main.yml
test/integration/targets/apt_repository/tasks/mode.yaml
test/integration/targets/apt_repository/tasks/mode_cleanup.yaml
test/integration/targets/args/aliases
test/integration/targets/args/runme.sh
test/integration/targets/argspec/aliases
test/integration/targets/argspec/runme.sh
test/integration/targets/argspec/collections/ansible_collections/foo/bar/plugins/modules/argspec.py
test/integration/targets/argspec/roles/argspec/meta/main.yml
test/integration/targets/argspec/roles/argspec/tasks/main.yml
test/integration/targets/argspec/roles/argspec/tasks/password_no_log.yml
test/integration/targets/assemble/aliases
test/integration/targets/assemble/files/fragment1
test/integration/targets/assemble/files/fragment2
test/integration/targets/assemble/files/fragment3
test/integration/targets/assemble/files/fragment4
test/integration/targets/assemble/files/fragment5
test/integration/targets/assemble/meta/main.yml
test/integration/targets/assemble/tasks/main.yml
test/integration/targets/assert/aliases
test/integration/targets/assert/lookup_plugins/yield_terms.py
test/integration/targets/assert/tasks/main.yml
test/integration/targets/async/aliases
test/integration/targets/async/callback_test.yml
test/integration/targets/async/check_task_test.yml
test/integration/targets/async/library/async_test.py
test/integration/targets/async/meta/main.yml
test/integration/targets/async/tasks/main.yml
test/integration/targets/async_extra_data/aliases
test/integration/targets/async_extra_data/runme.sh
test/integration/targets/async_extra_data/test_async.yml
test/integration/targets/async_extra_data/library/junkping.py
test/integration/targets/async_fail/aliases
test/integration/targets/async_fail/action_plugins/normal.py
test/integration/targets/async_fail/library/async_test.py
test/integration/targets/async_fail/meta/main.yml
test/integration/targets/async_fail/tasks/main.yml
test/integration/targets/become/aliases
test/integration/targets/become/files/copy.txt
test/integration/targets/become/meta/main.yml
test/integration/targets/become/tasks/become.yml
test/integration/targets/become/tasks/main.yml
test/integration/targets/become/vars/main.yml
test/integration/targets/become_su/aliases
test/integration/targets/become_su/files/sushim.sh
test/integration/targets/become_su/tasks/main.yml
test/integration/targets/become_sudo/aliases
test/integration/targets/become_sudo/files/sudoshim.sh
test/integration/targets/become_sudo/tasks/main.yml
test/integration/targets/become_unprivileged/aliases
test/integration/targets/become_unprivileged/cleanup_unpriv_users.yml
test/integration/targets/become_unprivileged/inventory
test/integration/targets/become_unprivileged/runme.sh
test/integration/targets/become_unprivileged/setup_unpriv_users.yml
test/integration/targets/become_unprivileged/action_plugins/tmpdir.py
test/integration/targets/become_unprivileged/chmod_acl_macos/test.yml
test/integration/targets/become_unprivileged/common_remote_group/cleanup.yml
test/integration/targets/become_unprivileged/common_remote_group/setup.yml
test/integration/targets/become_unprivileged/common_remote_group/test.yml
test/integration/targets/binary/aliases
test/integration/targets/binary/files/b64_latin1
test/integration/targets/binary/files/b64_utf8
test/integration/targets/binary/files/from_playbook
test/integration/targets/binary/meta/main.yml
test/integration/targets/binary/tasks/main.yml
test/integration/targets/binary/templates/b64_latin1_template.j2
test/integration/targets/binary/templates/b64_utf8_template.j2
test/integration/targets/binary/templates/from_playbook_template.j2
test/integration/targets/binary/vars/main.yml
test/integration/targets/binary_modules/aliases
test/integration/targets/binary_modules/build.py
test/integration/targets/binary_modules/download_binary_modules.yml
test/integration/targets/binary_modules/test.sh
test/integration/targets/binary_modules/test_binary_modules.yml
test/integration/targets/binary_modules/group_vars/all
test/integration/targets/binary_modules/library/.gitignore
test/integration/targets/binary_modules/library/helloworld.go
test/integration/targets/binary_modules/roles/test_binary_modules/tasks/main.yml
test/integration/targets/binary_modules_posix/aliases
test/integration/targets/binary_modules_posix/runme.sh
test/integration/targets/binary_modules_winrm/aliases
test/integration/targets/binary_modules_winrm/runme.sh
test/integration/targets/blockinfile/aliases
test/integration/targets/blockinfile/files/sshd_config
test/integration/targets/blockinfile/meta/main.yml
test/integration/targets/blockinfile/tasks/add_block_to_existing_file.yml
test/integration/targets/blockinfile/tasks/append_newline.yml
test/integration/targets/blockinfile/tasks/block_without_trailing_newline.yml
test/integration/targets/blockinfile/tasks/create_dir.yml
test/integration/targets/blockinfile/tasks/create_file.yml
test/integration/targets/blockinfile/tasks/diff.yml
test/integration/targets/blockinfile/tasks/file_without_trailing_newline.yml
test/integration/targets/blockinfile/tasks/insertafter.yml
test/integration/targets/blockinfile/tasks/insertbefore.yml
test/integration/targets/blockinfile/tasks/main.yml
test/integration/targets/blockinfile/tasks/multiline_search.yml
test/integration/targets/blockinfile/tasks/prepend_newline.yml
test/integration/targets/blockinfile/tasks/preserve_line_endings.yml
test/integration/targets/blockinfile/tasks/validate.yml
test/integration/targets/blocks/43191-2.yml
test/integration/targets/blocks/43191.yml
test/integration/targets/blocks/69848.yml
test/integration/targets/blocks/72725.yml
test/integration/targets/blocks/72781.yml
test/integration/targets/blocks/78612.yml
test/integration/targets/blocks/79711.yml
test/integration/targets/blocks/aliases
test/integration/targets/blocks/always_failure_no_rescue_rc.yml
test/integration/targets/blocks/always_failure_with_rescue_rc.yml
test/integration/targets/blocks/always_no_rescue_rc.yml
test/integration/targets/blocks/block_fail.yml
test/integration/targets/blocks/block_fail_tasks.yml
test/integration/targets/blocks/block_in_rescue.yml
test/integration/targets/blocks/block_rescue_vars.yml
test/integration/targets/blocks/fail.yml
test/integration/targets/blocks/finalized_task.yml
test/integration/targets/blocks/inherit_notify.yml
test/integration/targets/blocks/issue29047.yml
test/integration/targets/blocks/issue29047_tasks.yml
test/integration/targets/blocks/issue71306.yml
test/integration/targets/blocks/main.yml
test/integration/targets/blocks/nested_fail.yml
test/integration/targets/blocks/nested_nested_fail.yml
test/integration/targets/blocks/runme.sh
test/integration/targets/blocks/unsafe_failed_task.yml
test/integration/targets/blocks/roles/fail/tasks/main.yml
test/integration/targets/blocks/roles/role-69848-1/meta/main.yml
test/integration/targets/blocks/roles/role-69848-2/meta/main.yml
test/integration/targets/blocks/roles/role-69848-3/tasks/main.yml
test/integration/targets/builtin_vars_prompt/aliases
test/integration/targets/builtin_vars_prompt/runme.sh
test/integration/targets/builtin_vars_prompt/test-vars_prompt.py
test/integration/targets/builtin_vars_prompt/unsafe.yml
test/integration/targets/builtin_vars_prompt/unsupported.yml
test/integration/targets/builtin_vars_prompt/vars_prompt-1.yml
test/integration/targets/builtin_vars_prompt/vars_prompt-2.yml
test/integration/targets/builtin_vars_prompt/vars_prompt-3.yml
test/integration/targets/builtin_vars_prompt/vars_prompt-4.yml
test/integration/targets/builtin_vars_prompt/vars_prompt-5.yml
test/integration/targets/builtin_vars_prompt/vars_prompt-6.yml
test/integration/targets/builtin_vars_prompt/vars_prompt-7.yml
test/integration/targets/cache-plugins/aliases
test/integration/targets/cache-plugins/inspect_cache.yml
test/integration/targets/cache-plugins/runme.sh
test/integration/targets/cache-plugins/test.inventoryconfig.yml
test/integration/targets/cache-plugins/test_fact_gathering.yml
test/integration/targets/cache-plugins/test_inventory_cache.yml
test/integration/targets/cache-plugins/cache_plugins/dummy_cache.py
test/integration/targets/cache-plugins/inventory_plugins/test_inventoryconfig.py
test/integration/targets/callback-legacy-warnings/aliases
test/integration/targets/callback-legacy-warnings/runme.sh
test/integration/targets/callback-legacy-warnings/test.yml
test/integration/targets/callback-legacy-warnings/callback_plugins/legacy_warning_display.py
test/integration/targets/callback-legacy-warnings/library/noisy.py
test/integration/targets/callback_default/aliases
test/integration/targets/callback_default/callback_default.out.check_markers_dry.stderr
test/integration/targets/callback_default/callback_default.out.check_markers_dry.stdout
test/integration/targets/callback_default/callback_default.out.check_markers_wet.stderr
test/integration/targets/callback_default/callback_default.out.check_markers_wet.stdout
test/integration/targets/callback_default/callback_default.out.check_nomarkers_dry.stderr
test/integration/targets/callback_default/callback_default.out.check_nomarkers_dry.stdout
test/integration/targets/callback_default/callback_default.out.check_nomarkers_wet.stderr
test/integration/targets/callback_default/callback_default.out.check_nomarkers_wet.stdout
test/integration/targets/callback_default/callback_default.out.default.stderr
test/integration/targets/callback_default/callback_default.out.default.stdout
test/integration/targets/callback_default/callback_default.out.display_path_on_failure.stderr
test/integration/targets/callback_default/callback_default.out.display_path_on_failure.stdout
test/integration/targets/callback_default/callback_default.out.failed_to_stderr.stderr
test/integration/targets/callback_default/callback_default.out.failed_to_stderr.stdout
test/integration/targets/callback_default/callback_default.out.fqcn_free.stdout
test/integration/targets/callback_default/callback_default.out.free.stdout
test/integration/targets/callback_default/callback_default.out.hide_ok.stderr
test/integration/targets/callback_default/callback_default.out.hide_ok.stdout
test/integration/targets/callback_default/callback_default.out.hide_skipped.stderr
test/integration/targets/callback_default/callback_default.out.hide_skipped.stdout
test/integration/targets/callback_default/callback_default.out.hide_skipped_ok.stderr
test/integration/targets/callback_default/callback_default.out.hide_skipped_ok.stdout
test/integration/targets/callback_default/callback_default.out.host_pinned.stdout
test/integration/targets/callback_default/callback_default.out.include_role_fails.stderr
test/integration/targets/callback_default/callback_default.out.include_role_fails.stdout
test/integration/targets/callback_default/callback_default.out.result_format_yaml.stderr
test/integration/targets/callback_default/callback_default.out.result_format_yaml.stdout
test/integration/targets/callback_default/callback_default.out.result_format_yaml_lossy_verbose.stderr
test/integration/targets/callback_default/callback_default.out.result_format_yaml_lossy_verbose.stdout
test/integration/targets/callback_default/callback_default.out.result_format_yaml_verbose.stderr
test/integration/targets/callback_default/callback_default.out.result_format_yaml_verbose.stdout
test/integration/targets/callback_default/callback_default.out.yaml_result_format_yaml_verbose.stderr
test/integration/targets/callback_default/callback_default.out.yaml_result_format_yaml_verbose.stdout
test/integration/targets/callback_default/include_me.yml
test/integration/targets/callback_default/inventory
test/integration/targets/callback_default/no_implicit_meta_banners.yml
test/integration/targets/callback_default/runme.sh
test/integration/targets/callback_default/test.yml
test/integration/targets/callback_default/test_2.yml
test/integration/targets/callback_default/test_async.yml
test/integration/targets/callback_default/test_dryrun.yml
test/integration/targets/callback_default/test_include_role_fails.yml
test/integration/targets/callback_default/test_non_lockstep.yml
test/integration/targets/callback_default/test_yaml.yml
test/integration/targets/callback_results/aliases
test/integration/targets/callback_results/runme.sh
test/integration/targets/callback_results/task_name.yml
test/integration/targets/callback_results/callback_plugins/track_connections.py
test/integration/targets/changed_when/aliases
test/integration/targets/changed_when/meta/main.yml
test/integration/targets/changed_when/tasks/main.yml
test/integration/targets/check_mode/aliases
test/integration/targets/check_mode/check_mode-not-on-cli.yml
test/integration/targets/check_mode/check_mode-on-cli.yml
test/integration/targets/check_mode/check_mode.yml
test/integration/targets/check_mode/runme.sh
test/integration/targets/check_mode/roles/test_always_run/meta/main.yml
test/integration/targets/check_mode/roles/test_always_run/tasks/main.yml
test/integration/targets/check_mode/roles/test_check_mode/files/foo.txt
test/integration/targets/check_mode/roles/test_check_mode/tasks/main.yml
test/integration/targets/check_mode/roles/test_check_mode/templates/foo.j2
test/integration/targets/check_mode/roles/test_check_mode/vars/main.yml
test/integration/targets/cli/aliases
test/integration/targets/cli/runme.sh
test/integration/targets/cli/setup.yml
test/integration/targets/cli/test-cli.py
test/integration/targets/cli/test_k_and_K.py
test/integration/targets/cli/test_syntax/syntax_check.yml
test/integration/targets/cli/test_syntax/files/vaultsecret
test/integration/targets/cli/test_syntax/group_vars/all/testvault.yml
test/integration/targets/cli/test_syntax/roles/some_role/tasks/main.yml
test/integration/targets/collection/aliases
test/integration/targets/collection/setup.sh
test/integration/targets/collection/update-ignore.py
test/integration/targets/collections/a.statichost.yml
test/integration/targets/collections/aliases
test/integration/targets/collections/cache.statichost.yml
test/integration/targets/collections/check_populated_inventory.yml
test/integration/targets/collections/import_collection_pb.yml
test/integration/targets/collections/includeme.yml
test/integration/targets/collections/inventory_test.yml
test/integration/targets/collections/invocation_tests.yml
test/integration/targets/collections/noop.yml
test/integration/targets/collections/posix.yml
test/integration/targets/collections/redirected.statichost.yml
test/integration/targets/collections/runme.sh
test/integration/targets/collections/test_bypass_host_loop.yml
test/integration/targets/collections/test_collection_meta.yml
test/integration/targets/collections/test_redirect_list.yml
test/integration/targets/collections/test_task_resolved_plugin.sh
test/integration/targets/collections/vars_plugin_tests.sh
test/integration/targets/collections/windows.yml
test/integration/targets/collections/ansiballz_dupe/test_ansiballz_cache_dupe_shortname.yml
test/integration/targets/collections/ansiballz_dupe/collections/ansible_collections/duplicate/name/plugins/modules/ping.py
test/integration/targets/collections/collection_root_sys/ansible_collections/testns/coll_in_sys/plugins/modules/systestmodule.py
test/integration/targets/collections/collection_root_sys/ansible_collections/testns/testcoll/plugins/modules/maskedmodule.py
test/integration/targets/collections/collection_root_sys/ansible_collections/testns/testcoll/plugins/modules/testmodule.py
test/integration/targets/collections/collection_root_sys/ansible_collections/testns/testcoll/roles/maskedrole/tasks/main.yml
test/integration/targets/collections/collection_root_user/ansible_collections/ansible/builtin/plugins/modules/ping.py
test/integration/targets/collections/collection_root_user/ansible_collections/ansible/bullcoll/plugins/modules/bullmodule.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/othercoll/plugins/module_utils/formerly_testcoll_pkg/__init__.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/othercoll/plugins/module_utils/formerly_testcoll_pkg/submod.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testbroken/plugins/filter/broken_filter.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/meta/runtime.yml
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/playbooks/default_collection_playbook.yml
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/playbooks/play.yml
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/playbooks/roles/non_coll_role/library/embedded_module.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/playbooks/roles/non_coll_role/tasks/main.yml
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/playbooks/roles/non_coll_role_to_call/tasks/main.yml
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/playbooks/type/play.yml
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/playbooks/type/subtype/play.yml
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/action/bypass_host_loop.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/action/plugin_lookup.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/action/subclassed_normal.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/action/uses_redirected_import.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/action/action_subdir/subdir_ping_action.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/callback/usercallback.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/connection/localconn.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/doc_fragments/frag.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/filter/myfilters.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/filter/myfilters2.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/filter/filter_subdir/my_subdir_filters.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/lookup/mylookup.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/lookup/mylookup2.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/lookup/lookup_subdir/my_subdir_lookup.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/AnotherCSMU.cs
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/MyCSMU.cs
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/MyCSMUOptional.cs
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/MyPSMU.psm1
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/MyPSMUOptional.psm1
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/base.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/leaf.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/secondary.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/subpkg_with_init.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/nested_same/__init__.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/nested_same/nested_same/__init__.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/nested_same/nested_same/nested_same.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/subpkg/__init__.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/subpkg/subcs.cs
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/subpkg/submod.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/subpkg/subps.psm1
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/subpkg_with_init/__init__.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/module_utils/subpkg_with_init/mod_in_subpkg_with_init.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/deprecated_ping.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/ping.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/testmodule.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/testmodule_bad_docfrags.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_base_mu_granular_nested_import.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_collection_redirected_mu.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_core_redirected_mu.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_leaf_mu_flat_import.bak
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_leaf_mu_flat_import.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_leaf_mu_flat_import.yml
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_leaf_mu_granular_import.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_leaf_mu_module_import_from.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_mu_missing.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_mu_missing_redirect_collection.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_mu_missing_redirect_module.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_nested_same_as_func.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/uses_nested_same_as_module.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/win_csbasic_only.ps1
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/win_selfcontained.ps1
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/win_selfcontained.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/win_uses_coll_csmu.ps1
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/win_uses_coll_psmu.ps1
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/win_uses_optional.ps1
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/modules/module_subdir/subdir_ping_module.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/test/mytests.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/test/mytests2.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/test/test_subdir/my_subdir_tests.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/plugins/vars/custom_vars.py
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/roles/call_standalone/tasks/main.yml
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/roles/calls_intra_collection_dep_role_unqualified/meta/main.yml
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/roles/calls_intra_collection_dep_role_unqualified/tasks/main.yml
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/roles/common_handlers/handlers/main.yml
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/roles/role_subdir/subdir_testrole/tasks/main.yml
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/roles/test_fqcn_handlers/meta/main.yml
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/roles/test_fqcn_handlers/tasks/main.yml
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/roles/testrole/meta/main.yml
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/roles/testrole/tasks/main.yml
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/roles/testrole_main_yaml/meta/main.yml
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testcoll/roles/testrole_main_yaml/tasks/main.yml
test/integration/targets/collections/collection_root_user/ansible_collections/testns/testredirect/meta/runtime.yml
test/integration/targets/collections/collections/ansible_collections/me/mycoll1/plugins/action/action1.py
test/integration/targets/collections/collections/ansible_collections/me/mycoll1/plugins/modules/action1.py
test/integration/targets/collections/collections/ansible_collections/me/mycoll2/plugins/modules/module1.py
test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/cache/custom_jsonfile.py
test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/inventory/statichost.py
test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/module_utils/__init__.py
test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/module_utils/sub1/__init__.py
test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/module_utils/sub1/foomodule.py
test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/modules/contentadjmodule.py
test/integration/targets/collections/collections/ansible_collections/testns/content_adj/plugins/vars/custom_adj_vars.py
test/integration/targets/collections/custom_vars_plugins/v1_vars_plugin.py
test/integration/targets/collections/custom_vars_plugins/v2_vars_plugin.py
test/integration/targets/collections/filter_plugins/override_formerly_core_masked_filter.py
test/integration/targets/collections/library/ping.py
test/integration/targets/collections/roles/standalone/tasks/main.yml
test/integration/targets/collections/roles/testrole/tasks/main.yml
test/integration/targets/collections/test_plugins/override_formerly_core_masked_test.py
test/integration/targets/collections/test_task_resolved_plugin/fqcn.yml
test/integration/targets/collections/test_task_resolved_plugin/unqualified.yml
test/integration/targets/collections/test_task_resolved_plugin/unqualified_and_collections_kw.yml
test/integration/targets/collections/test_task_resolved_plugin/action_plugins/legacy_action.py
test/integration/targets/collections/test_task_resolved_plugin/callback_plugins/display_resolved_action.py
test/integration/targets/collections/test_task_resolved_plugin/collections/ansible_collections/test_ns/test_coll/meta/runtime.yml
test/integration/targets/collections/test_task_resolved_plugin/collections/ansible_collections/test_ns/test_coll/plugins/action/collection_action.py
test/integration/targets/collections/test_task_resolved_plugin/collections/ansible_collections/test_ns/test_coll/plugins/modules/collection_module.py
test/integration/targets/collections/test_task_resolved_plugin/library/legacy_module.py
test/integration/targets/collections/testcoll2/plugins/modules/testmodule2.py
test/integration/targets/collections_plugin_namespace/aliases
test/integration/targets/collections_plugin_namespace/runme.sh
test/integration/targets/collections_plugin_namespace/test.yml
test/integration/targets/collections_plugin_namespace/collection_root/ansible_collections/my_ns/my_col/plugins/filter/test_filter.py
test/integration/targets/collections_plugin_namespace/collection_root/ansible_collections/my_ns/my_col/plugins/lookup/lookup_name.py
test/integration/targets/collections_plugin_namespace/collection_root/ansible_collections/my_ns/my_col/plugins/lookup/lookup_no_future_boilerplate.py
test/integration/targets/collections_plugin_namespace/collection_root/ansible_collections/my_ns/my_col/plugins/test/test_test.py
test/integration/targets/collections_plugin_namespace/collection_root/ansible_collections/my_ns/my_col/roles/test/tasks/main.yml
test/integration/targets/collections_relative_imports/aliases
test/integration/targets/collections_relative_imports/runme.sh
test/integration/targets/collections_relative_imports/test.yml
test/integration/targets/collections_relative_imports/windows.yml
test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/module_utils/PSRel1.psm1
test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/module_utils/PSRel4.psm1
test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/module_utils/my_util1.py
test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/module_utils/my_util2.py
test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/module_utils/my_util3.py
test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/module_utils/sub_pkg/PSRel2.psm1
test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/modules/my_module.py
test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/modules/win_relative.ps1
test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/plugins/modules/win_relative_optional.ps1
test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col/roles/test/tasks/main.yml
test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col2/plugins/module_utils/PSRel3.psm1
test/integration/targets/collections_relative_imports/collection_root/ansible_collections/my_ns/my_col2/plugins/module_utils/sub_pkg/CSRel4.cs
test/integration/targets/collections_runtime_pythonpath/aliases
test/integration/targets/collections_runtime_pythonpath/runme.sh
test/integration/targets/collections_runtime_pythonpath/ansible-collection-python-dist-boo/pyproject.toml
test/integration/targets/collections_runtime_pythonpath/ansible-collection-python-dist-boo/setup.cfg
test/integration/targets/collections_runtime_pythonpath/ansible-collection-python-dist-boo/ansible_collections/python/dist/plugins/modules/boo.py
test/integration/targets/collections_runtime_pythonpath/ansible-collection-python-dist-foo/ansible_collections/python/dist/plugins/modules/boo.py
test/integration/targets/command_shell/aliases
test/integration/targets/command_shell/files/create_afile.sh
test/integration/targets/command_shell/files/remove_afile.sh
test/integration/targets/command_shell/files/test.sh
test/integration/targets/command_shell/meta/main.yml
test/integration/targets/command_shell/scripts/yoink.sh
test/integration/targets/command_shell/tasks/main.yml
test/integration/targets/common_network/aliases
test/integration/targets/common_network/tasks/main.yml
test/integration/targets/common_network/test_plugins/is_mac.py
test/integration/targets/conditionals/aliases
test/integration/targets/conditionals/broken_conditionals.yml
test/integration/targets/conditionals/output_validation_tests.yml
test/integration/targets/conditionals/play.yml
test/integration/targets/conditionals/runme.sh
test/integration/targets/conditionals/vars/main.yml
test/integration/targets/config/aliases
test/integration/targets/config/inline_comment_ansible.cfg
test/integration/targets/config/runme.sh
test/integration/targets/config/type_munging.cfg
test/integration/targets/config/types.yml
test/integration/targets/config/validation.yml
test/integration/targets/config/files/types.env
test/integration/targets/config/files/types.ini
test/integration/targets/config/files/types.vars
test/integration/targets/config/files/types_dump.txt
test/integration/targets/config/lookup_plugins/bogus.py
test/integration/targets/config/lookup_plugins/casting.py
test/integration/targets/config/lookup_plugins/casting_individual.py
test/integration/targets/config/lookup_plugins/types.py
test/integration/targets/connection/aliases
test/integration/targets/connection/test.sh
test/integration/targets/connection/test_connection.yml
test/integration/targets/connection/test_reset_connection.yml
test/integration/targets/connection/test_reset_connection_templated.yml
test/integration/targets/connection_delegation/aliases
test/integration/targets/connection_delegation/inventory.ini
test/integration/targets/connection_delegation/runme.sh
test/integration/targets/connection_delegation/test.yml
test/integration/targets/connection_delegation/action_plugins/delegation_action.py
test/integration/targets/connection_delegation/connection_plugins/delegation_connection.py
test/integration/targets/connection_local/aliases
test/integration/targets/connection_local/runme.sh
test/integration/targets/connection_local/test_become_password_handling.yml
test/integration/targets/connection_local/test_connection.inventory
test/integration/targets/connection_local/test_network_connection.inventory
test/integration/targets/connection_local/connection_plugins/network_noop.py
test/integration/targets/connection_local/files/sudoshim.sh
test/integration/targets/connection_paramiko_ssh/aliases
test/integration/targets/connection_paramiko_ssh/runme.sh
test/integration/targets/connection_paramiko_ssh/test.sh
test/integration/targets/connection_paramiko_ssh/test_connection.inventory
test/integration/targets/connection_psrp/aliases
test/integration/targets/connection_psrp/runme.sh
test/integration/targets/connection_psrp/test_connection.inventory.j2
test/integration/targets/connection_psrp/tests.yml
test/integration/targets/connection_psrp/files/empty.txt
test/integration/targets/connection_remote_is_local/aliases
test/integration/targets/connection_remote_is_local/test.yml
test/integration/targets/connection_remote_is_local/connection_plugins/remote_is_local.py
test/integration/targets/connection_remote_is_local/tasks/main.yml
test/integration/targets/connection_ssh/aliases
test/integration/targets/connection_ssh/check_ssh_defaults.yml
test/integration/targets/connection_ssh/posix.sh
test/integration/targets/connection_ssh/runme.sh
test/integration/targets/connection_ssh/test_connection.inventory
test/integration/targets/connection_ssh/test_ssh_askpass.yml
test/integration/targets/connection_ssh/test_ssh_defaults.cfg
test/integration/targets/connection_ssh/test_unreachable_become_timeout.yml
test/integration/targets/connection_ssh/verify_config.yml
test/integration/targets/connection_ssh/files/port_override_ssh.cfg
test/integration/targets/connection_windows_ssh/aliases
test/integration/targets/connection_windows_ssh/runme.sh
test/integration/targets/connection_windows_ssh/test_connection.inventory.j2
test/integration/targets/connection_windows_ssh/tests.yml
test/integration/targets/connection_windows_ssh/tests_fetch.yml
test/integration/targets/connection_windows_ssh/windows.sh
test/integration/targets/connection_winrm/aliases
test/integration/targets/connection_winrm/runme.sh
test/integration/targets/connection_winrm/test_connection.inventory.j2
test/integration/targets/connection_winrm/tests.yml
test/integration/targets/controller/aliases
test/integration/targets/controller/tasks/main.yml
test/integration/targets/copy/aliases
test/integration/targets/copy/defaults/main.yml
test/integration/targets/copy/files/foo.txt
test/integration/targets/copy/files-different/vault/readme.txt
test/integration/targets/copy/files-different/vault/vault-file
test/integration/targets/copy/files-different/vault/folder/nested-vault-file
test/integration/targets/copy/files/subdir/bar.txt
test/integration/targets/copy/files/subdir/subdir1/empty.txt
test/integration/targets/copy/files/subdir/subdir2/baz.txt
test/integration/targets/copy/files/subdir/subdir2/subdir3/subdir4/qux.txt
test/integration/targets/copy/meta/main.yml
test/integration/targets/copy/tasks/acls.yml
test/integration/targets/copy/tasks/check_mode.yml
test/integration/targets/copy/tasks/dest_in_non_existent_directories.yml
test/integration/targets/copy/tasks/dest_in_non_existent_directories_remote_src.yml
test/integration/targets/copy/tasks/main.yml
test/integration/targets/copy/tasks/no_log.yml
test/integration/targets/copy/tasks/selinux.yml
test/integration/targets/copy/tasks/setgid.yml
test/integration/targets/copy/tasks/src_file_dest_file_in_non_existent_dir.yml
test/integration/targets/copy/tasks/src_file_dest_file_in_non_existent_dir_remote_src.yml
test/integration/targets/copy/tasks/src_remote_file_is_not_file.yml
test/integration/targets/copy/tasks/tests.yml
test/integration/targets/cron/aliases
test/integration/targets/cron/meta/main.yml
test/integration/targets/cron/tasks/main.yml
test/integration/targets/cron/vars/alpine.yml
test/integration/targets/cron/vars/default.yml
test/integration/targets/data_tagging_controller/aliases
test/integration/targets/data_tagging_controller/expected_stderr.txt
test/integration/targets/data_tagging_controller/expected_stdout.txt
test/integration/targets/data_tagging_controller/hosts
test/integration/targets/data_tagging_controller/output_tests.yml
test/integration/targets/data_tagging_controller/runme.sh
test/integration/targets/data_tagging_controller/untrusted_propagation.yml
test/integration/targets/data_tagging_controller/library/deepresp.py
test/integration/targets/data_tagging_controller/library/tagging_sample.py
test/integration/targets/dataloader/aliases
test/integration/targets/dataloader/attempt_to_load_invalid_json.yml
test/integration/targets/dataloader/runme.sh
test/integration/targets/dataloader/vars/invalid.json
test/integration/targets/deb822_repository/aliases
test/integration/targets/deb822_repository/meta/main.yml
test/integration/targets/deb822_repository/tasks/install.yml
test/integration/targets/deb822_repository/tasks/main.yml
test/integration/targets/deb822_repository/tasks/test.yml
test/integration/targets/debconf/aliases
test/integration/targets/debconf/meta/main.yml
test/integration/targets/debconf/tasks/main.yml
test/integration/targets/debug/aliases
test/integration/targets/debug/args_templating.yml
test/integration/targets/debug/errors.yml
test/integration/targets/debug/main.yml
test/integration/targets/debug/main_fqcn.yml
test/integration/targets/debug/nosetfacts.yml
test/integration/targets/debug/runme.sh
test/integration/targets/debugger/aliases
test/integration/targets/debugger/inventory
test/integration/targets/debugger/runme.sh
test/integration/targets/debugger/test_run_once.py
test/integration/targets/debugger/test_run_once_playbook.yml
test/integration/targets/delegate_to/aliases
test/integration/targets/delegate_to/delegate_and_nolog.yml
test/integration/targets/delegate_to/delegate_facts_block.yml
test/integration/targets/delegate_to/delegate_facts_loop.yml
test/integration/targets/delegate_to/delegate_local_from_root.yml
test/integration/targets/delegate_to/delegate_to_lookup_context.yml
test/integration/targets/delegate_to/delegate_vars_handling.yml
test/integration/targets/delegate_to/delegate_with_fact_from_delegate_host.yml
test/integration/targets/delegate_to/discovery_applied.yml
test/integration/targets/delegate_to/has_hostvars.yml
test/integration/targets/delegate_to/inventory
test/integration/targets/delegate_to/inventory_interpreters
test/integration/targets/delegate_to/resolve_vars.yml
test/integration/targets/delegate_to/runme.sh
test/integration/targets/delegate_to/test_delegate_to.yml
test/integration/targets/delegate_to/test_delegate_to_lookup_context.yml
test/integration/targets/delegate_to/test_delegate_to_loop_caching.yml
test/integration/targets/delegate_to/test_delegate_to_loop_randomness.yml
test/integration/targets/delegate_to/test_loop_control.yml
test/integration/targets/delegate_to/test_random_delegate_to_with_loop.yml
test/integration/targets/delegate_to/test_random_delegate_to_without_loop.yml
test/integration/targets/delegate_to/verify_interpreter.yml
test/integration/targets/delegate_to/connection_plugins/fakelocal.py
test/integration/targets/delegate_to/files/testfile
test/integration/targets/delegate_to/library/detect_interpreter.py
test/integration/targets/delegate_to/roles/delegate_to_lookup_context/tasks/main.yml
test/integration/targets/delegate_to/roles/delegate_to_lookup_context/templates/one.j2
test/integration/targets/delegate_to/roles/delegate_to_lookup_context/templates/two.j2
test/integration/targets/delegate_to/roles/test_template/templates/foo.j2
test/integration/targets/deprecations/aliases
test/integration/targets/deprecations/deprecated.yml
test/integration/targets/deprecations/entry_key_deprecated.cfg
test/integration/targets/deprecations/entry_key_deprecated2.cfg
test/integration/targets/deprecations/entry_key_not_deprecated.cfg
test/integration/targets/deprecations/runme.sh
test/integration/targets/deprecations/cache_plugins/notjsonfile.py
test/integration/targets/deprecations/collections/ansible_collections/foo/bar/plugins/__init__.py
test/integration/targets/deprecations/collections/ansible_collections/foo/bar/plugins/action/__init__.py
test/integration/targets/deprecations/collections/ansible_collections/foo/bar/plugins/action/noisy_action.py
test/integration/targets/deprecations/collections/ansible_collections/foo/bar/plugins/module_utils/shared_deprecation.py
test/integration/targets/deprecations/collections/ansible_collections/foo/bar/plugins/modules/__init__.py
test/integration/targets/deprecations/collections/ansible_collections/foo/bar/plugins/modules/noisy.py
test/integration/targets/deprecations/library/removeoption.py
test/integration/targets/deprecations/library/willremove.py
test/integration/targets/dict_transformations/aliases
test/integration/targets/dict_transformations/library/convert_camelCase.py
test/integration/targets/dict_transformations/library/convert_snake_case.py
test/integration/targets/dict_transformations/tasks/main.yml
test/integration/targets/dict_transformations/tasks/test_convert_camelCase.yml
test/integration/targets/dict_transformations/tasks/test_convert_snake_case.yml
test/integration/targets/dnf/aliases
test/integration/targets/dnf/filter_plugins/dnf_module_list.py
test/integration/targets/dnf/meta/main.yml
test/integration/targets/dnf/tasks/cacheonly.yml
test/integration/targets/dnf/tasks/dnf.yml
test/integration/targets/dnf/tasks/dnf_group_remove.yml
test/integration/targets/dnf/tasks/dnfinstallroot.yml
test/integration/targets/dnf/tasks/dnfreleasever.yml
test/integration/targets/dnf/tasks/filters.yml
test/integration/targets/dnf/tasks/filters_check_mode.yml
test/integration/targets/dnf/tasks/gpg.yml
test/integration/targets/dnf/tasks/logging.yml
test/integration/targets/dnf/tasks/main.yml
test/integration/targets/dnf/tasks/modularity.yml
test/integration/targets/dnf/tasks/multilib.yml
test/integration/targets/dnf/tasks/repo.yml
test/integration/targets/dnf/tasks/skip_broken_and_nobest.yml
test/integration/targets/dnf/tasks/test_sos_removal.yml
test/integration/targets/dnf/vars/main.yml
test/integration/targets/dnf5/aliases
test/integration/targets/dnf5/playbook.yml
test/integration/targets/dnf5/runme.sh
test/integration/targets/dpkg_selections/aliases
test/integration/targets/dpkg_selections/defaults/main.yaml
test/integration/targets/dpkg_selections/tasks/dpkg_selections.yaml
test/integration/targets/dpkg_selections/tasks/main.yaml
test/integration/targets/embedded_module/aliases
test/integration/targets/embedded_module/library/test_integration_module
test/integration/targets/embedded_module/tasks/main.yml
test/integration/targets/entry_points/aliases
test/integration/targets/entry_points/runme.sh
test/integration/targets/environment/aliases
test/integration/targets/environment/runme.sh
test/integration/targets/environment/test_environment.yml
test/integration/targets/error_from_connection/aliases
test/integration/targets/error_from_connection/inventory
test/integration/targets/error_from_connection/play.yml
test/integration/targets/error_from_connection/runme.sh
test/integration/targets/error_from_connection/connection_plugins/dummy.py
test/integration/targets/expect/aliases
test/integration/targets/expect/files/foo.txt
test/integration/targets/expect/files/test_command.py
test/integration/targets/expect/files/test_non_utf8_command.py
test/integration/targets/expect/meta/main.yml
test/integration/targets/expect/tasks/main.yml
test/integration/targets/facts_d/aliases
test/integration/targets/facts_d/files/bad.fact
test/integration/targets/facts_d/files/basdscript.fact
test/integration/targets/facts_d/files/goodscript.fact
test/integration/targets/facts_d/files/preferences.fact
test/integration/targets/facts_d/files/unreadable.fact
test/integration/targets/facts_d/meta/main.yml
test/integration/targets/facts_d/tasks/main.yml
test/integration/targets/facts_linux_network/aliases
test/integration/targets/facts_linux_network/meta/main.yml
test/integration/targets/facts_linux_network/tasks/main.yml
test/integration/targets/failed_when/aliases
test/integration/targets/failed_when/tasks/main.yml
test/integration/targets/fetch/aliases
test/integration/targets/fetch/cleanup.yml
test/integration/targets/fetch/run_fetch_tests.yml
test/integration/targets/fetch/runme.sh
test/integration/targets/fetch/setup_unreadable_test.yml
test/integration/targets/fetch/test_unreadable_with_stat.yml
test/integration/targets/fetch/injection/avoid_slurp_return.yml
test/integration/targets/fetch/injection/here.txt
test/integration/targets/fetch/injection/library/slurp.py
test/integration/targets/fetch/roles/fetch_tests/defaults/main.yml
test/integration/targets/fetch/roles/fetch_tests/handlers/main.yml
test/integration/targets/fetch/roles/fetch_tests/meta/main.yml
test/integration/targets/fetch/roles/fetch_tests/tasks/fail_on_missing.yml
test/integration/targets/fetch/roles/fetch_tests/tasks/failures.yml
test/integration/targets/fetch/roles/fetch_tests/tasks/main.yml
test/integration/targets/fetch/roles/fetch_tests/tasks/normal.yml
test/integration/targets/fetch/roles/fetch_tests/tasks/setup.yml
test/integration/targets/fetch/roles/fetch_tests/tasks/symlink.yml
test/integration/targets/fetch/roles/fetch_tests/vars/Darwin.yml
test/integration/targets/fetch/roles/fetch_tests/vars/default.yml
test/integration/targets/file/aliases
test/integration/targets/file/defaults/main.yml
test/integration/targets/file/files/foo.txt
test/integration/targets/file/files/foobar/fileA
test/integration/targets/file/files/foobar/fileB
test/integration/targets/file/files/foobar/directory/fileC
test/integration/targets/file/files/foobar/directory/fileD
test/integration/targets/file/handlers/main.yml
test/integration/targets/file/meta/main.yml
test/integration/targets/file/tasks/diff.yml
test/integration/targets/file/tasks/diff_peek.yml
test/integration/targets/file/tasks/directory_as_dest.yml
test/integration/targets/file/tasks/initialize.yml
test/integration/targets/file/tasks/link_follow.yml
test/integration/targets/file/tasks/link_rewrite.yml
test/integration/targets/file/tasks/main.yml
test/integration/targets/file/tasks/modification_time.yml
test/integration/targets/file/tasks/selinux_tests.yml
test/integration/targets/file/tasks/state_link.yml
test/integration/targets/file/tasks/unicode_path.yml
test/integration/targets/filter_core/aliases
test/integration/targets/filter_core/handle_undefined_type_errors.yml
test/integration/targets/filter_core/runme.sh
test/integration/targets/filter_core/runme.yml
test/integration/targets/filter_core/files/9851.txt
test/integration/targets/filter_core/files/foo.txt
test/integration/targets/filter_core/files/fileglob/one.txt
test/integration/targets/filter_core/files/fileglob/two.txt
test/integration/targets/filter_core/host_vars/localhost
test/integration/targets/filter_core/tasks/main.yml
test/integration/targets/filter_core/templates/foo.j2
test/integration/targets/filter_core/vars/main.yml
test/integration/targets/filter_encryption/aliases
test/integration/targets/filter_encryption/tasks/main.yml
test/integration/targets/filter_encryption/vars/main.yml
test/integration/targets/filter_mathstuff/aliases
test/integration/targets/filter_mathstuff/runme.sh
test/integration/targets/filter_mathstuff/runme.yml
test/integration/targets/filter_mathstuff/host_vars/localhost.yml
test/integration/targets/filter_mathstuff/tasks/main.yml
test/integration/targets/filter_mathstuff/vars/defined_later.yml
test/integration/targets/filter_mathstuff/vars/main.yml
test/integration/targets/filter_urls/aliases
test/integration/targets/filter_urls/tasks/main.yml
test/integration/targets/filter_urlsplit/aliases
test/integration/targets/filter_urlsplit/tasks/main.yml
test/integration/targets/find/aliases
test/integration/targets/find/files/a.txt
test/integration/targets/find/files/hello_world.gbk
test/integration/targets/find/files/log.txt
test/integration/targets/find/meta/main.yml
test/integration/targets/find/tasks/main.yml
test/integration/targets/find/tasks/mode.yml
test/integration/targets/fork_safe_stdio/aliases
test/integration/targets/fork_safe_stdio/hosts
test/integration/targets/fork_safe_stdio/run-with-pty.py
test/integration/targets/fork_safe_stdio/runme.sh
test/integration/targets/fork_safe_stdio/test.yml
test/integration/targets/fork_safe_stdio/vendored_pty.py
test/integration/targets/fork_safe_stdio/callback_plugins/spewstdio.py
test/integration/targets/gathering/aliases
test/integration/targets/gathering/explicit.yml
test/integration/targets/gathering/implicit.yml
test/integration/targets/gathering/runme.sh
test/integration/targets/gathering/smart.yml
test/integration/targets/gathering/uuid.fact
test/integration/targets/gathering_facts/aliases
test/integration/targets/gathering_facts/inventory
test/integration/targets/gathering_facts/one_two.json
test/integration/targets/gathering_facts/prevent_clobbering.yml
test/integration/targets/gathering_facts/runme.sh
test/integration/targets/gathering_facts/smart_added.yml
test/integration/targets/gathering_facts/test_gathering_facts.yml
test/integration/targets/gathering_facts/test_module_defaults.yml
test/integration/targets/gathering_facts/test_prevent_injection.yml
test/integration/targets/gathering_facts/test_run_once.yml
test/integration/targets/gathering_facts/two_one.json
test/integration/targets/gathering_facts/uuid.fact
test/integration/targets/gathering_facts/verify_merge_facts.yml
test/integration/targets/gathering_facts/verify_subset.yml
test/integration/targets/gathering_facts/cache_plugins/none.py
test/integration/targets/gathering_facts/collections/ansible_collections/cisco/ios/plugins/modules/ios_facts.py
test/integration/targets/gathering_facts/library/bogus_facts
test/integration/targets/gathering_facts/library/dummy1
test/integration/targets/gathering_facts/library/dummy2
test/integration/targets/gathering_facts/library/dummy3
test/integration/targets/gathering_facts/library/facts_one
test/integration/targets/gathering_facts/library/facts_two
test/integration/targets/gathering_facts/library/file_utils.py
test/integration/targets/gathering_facts/library/slow
test/integration/targets/get_url/aliases
test/integration/targets/get_url/files/testserver.py
test/integration/targets/get_url/meta/main.yml
test/integration/targets/get_url/tasks/ciphers.yml
test/integration/targets/get_url/tasks/hashlib.yml
test/integration/targets/get_url/tasks/main.yml
test/integration/targets/get_url/tasks/use_gssapi.yml
test/integration/targets/get_url/tasks/use_netrc.yml
test/integration/targets/getent/aliases
test/integration/targets/getent/meta/main.yml
test/integration/targets/getent/tasks/main.yml
test/integration/targets/git/aliases
test/integration/targets/git/handlers/cleanup-default.yml
test/integration/targets/git/handlers/cleanup-freebsd.yml
test/integration/targets/git/handlers/main.yml
test/integration/targets/git/meta/main.yml
test/integration/targets/git/tasks/ambiguous-ref.yml
test/integration/targets/git/tasks/archive.yml
test/integration/targets/git/tasks/change-repo-url.yml
test/integration/targets/git/tasks/checkout-new-tag.yml
test/integration/targets/git/tasks/depth.yml
test/integration/targets/git/tasks/forcefully-fetch-tag.yml
test/integration/targets/git/tasks/formats.yml
test/integration/targets/git/tasks/gpg-verification.yml
test/integration/targets/git/tasks/localmods.yml
test/integration/targets/git/tasks/main.yml
test/integration/targets/git/tasks/missing_hostkey.yml
test/integration/targets/git/tasks/missing_hostkey_acceptnew.yml
test/integration/targets/git/tasks/no-destination.yml
test/integration/targets/git/tasks/reset-origin.yml
test/integration/targets/git/tasks/separate-git-dir.yml
test/integration/targets/git/tasks/setup-local-repos.yml
test/integration/targets/git/tasks/setup.yml
test/integration/targets/git/tasks/single-branch.yml
test/integration/targets/git/tasks/specific-revision.yml
test/integration/targets/git/tasks/submodules.yml
test/integration/targets/git/vars/main.yml
test/integration/targets/group/aliases
test/integration/targets/group/files/get_free_gid.py
test/integration/targets/group/files/get_gid_for_group.py
test/integration/targets/group/files/grouplist.sh
test/integration/targets/group/meta/main.yml
test/integration/targets/group/tasks/main.yml
test/integration/targets/group/tasks/test_create_group_min_max.yml
test/integration/targets/group/tasks/tests.yml
test/integration/targets/group_by/aliases
test/integration/targets/group_by/create_groups.yml
test/integration/targets/group_by/inventory.group_by
test/integration/targets/group_by/runme.sh
test/integration/targets/group_by/test_group_by.yml
test/integration/targets/group_by/test_group_by_skipped.yml
test/integration/targets/group_by/group_vars/all
test/integration/targets/group_by/group_vars/camelus
test/integration/targets/group_by/group_vars/vicugna
test/integration/targets/handler_race/aliases
test/integration/targets/handler_race/inventory
test/integration/targets/handler_race/runme.sh
test/integration/targets/handler_race/test_handler_race.yml
test/integration/targets/handler_race/roles/do_handlers/handlers/main.yml
test/integration/targets/handler_race/roles/do_handlers/tasks/main.yml
test/integration/targets/handler_race/roles/more_sleep/tasks/main.yml
test/integration/targets/handler_race/roles/random_sleep/tasks/main.yml
test/integration/targets/handlers/46447.yml
test/integration/targets/handlers/52561.yml
test/integration/targets/handlers/54991.yml
test/integration/targets/handlers/58841.yml
test/integration/targets/handlers/79776-handlers.yml
test/integration/targets/handlers/79776.yml
test/integration/targets/handlers/80880.yml
test/integration/targets/handlers/82241.yml
test/integration/targets/handlers/aliases
test/integration/targets/handlers/force_handlers_blocks_81533-1.yml
test/integration/targets/handlers/force_handlers_blocks_81533-2.yml
test/integration/targets/handlers/from_handlers.yml
test/integration/targets/handlers/handler_notify_earlier_handler.yml
test/integration/targets/handlers/handlers.yml
test/integration/targets/handlers/handlers_lockstep_82307.yml
test/integration/targets/handlers/handlers_lockstep_83019-include-nested.yml
test/integration/targets/handlers/handlers_lockstep_83019-include.yml
test/integration/targets/handlers/handlers_lockstep_83019.yml
test/integration/targets/handlers/include_handlers_fail_force-handlers.yml
test/integration/targets/handlers/include_handlers_fail_force.yml
test/integration/targets/handlers/inventory.handlers
test/integration/targets/handlers/nested_flush_handlers_failure_force.yml
test/integration/targets/handlers/order.yml
test/integration/targets/handlers/runme.sh
test/integration/targets/handlers/tagged_play.yml
test/integration/targets/handlers/test_block_as_handler-import.yml
test/integration/targets/handlers/test_block_as_handler-include.yml
test/integration/targets/handlers/test_block_as_handler-include_import-handlers.yml
test/integration/targets/handlers/test_block_as_handler.yml
test/integration/targets/handlers/test_flush_handlers_as_handler.yml
test/integration/targets/handlers/test_flush_handlers_rescue_always.yml
test/integration/targets/handlers/test_flush_in_rescue_always.yml
test/integration/targets/handlers/test_force_handlers.yml
test/integration/targets/handlers/test_fqcn_meta_flush_handlers.yml
test/integration/targets/handlers/test_handlers.yml
test/integration/targets/handlers/test_handlers_any_errors_fatal.yml
test/integration/targets/handlers/test_handlers_include.yml
test/integration/targets/handlers/test_handlers_include_role.yml
test/integration/targets/handlers/test_handlers_including_task.yml
test/integration/targets/handlers/test_handlers_inexistent_notify.yml
test/integration/targets/handlers/test_handlers_infinite_loop.yml
test/integration/targets/handlers/test_handlers_listen.yml
test/integration/targets/handlers/test_handlers_meta.yml
test/integration/targets/handlers/test_handlers_template_run_once.yml
test/integration/targets/handlers/test_include_role_handler_once.yml
test/integration/targets/handlers/test_include_tasks_in_include_role.yml
test/integration/targets/handlers/test_listen_role_dedup.yml
test/integration/targets/handlers/test_listening_handlers.yml
test/integration/targets/handlers/test_multiple_handlers_with_recursive_notification.yml
test/integration/targets/handlers/test_notify_included-handlers.yml
test/integration/targets/handlers/test_notify_included.yml
test/integration/targets/handlers/test_role_as_handler.yml
test/integration/targets/handlers/test_role_handlers_including_tasks.yml
test/integration/targets/handlers/test_run_once.yml
test/integration/targets/handlers/test_skip_flush.yml
test/integration/targets/handlers/test_templating_in_handlers.yml
test/integration/targets/handlers/collections/ansible_collections/ns/col/roles/test_handlers_listen/handlers/main.yml
test/integration/targets/handlers/roles/import_template_handler_names/tasks/main.yml
test/integration/targets/handlers/roles/include_role_include_tasks_handler/handlers/include_handlers.yml
test/integration/targets/handlers/roles/include_role_include_tasks_handler/handlers/main.yml
test/integration/targets/handlers/roles/include_role_include_tasks_handler/tasks/main.yml
test/integration/targets/handlers/roles/r1-dep_chain-vars/defaults/main.yml
test/integration/targets/handlers/roles/r1-dep_chain-vars/tasks/main.yml
test/integration/targets/handlers/roles/r2-dep_chain-vars/handlers/main.yml
test/integration/targets/handlers/roles/r2-dep_chain-vars/tasks/main.yml
test/integration/targets/handlers/roles/role-82241/handlers/main.yml
test/integration/targets/handlers/roles/role-82241/tasks/entry_point.yml
test/integration/targets/handlers/roles/role-82241/tasks/included_tasks.yml
test/integration/targets/handlers/roles/template_handler_names/handlers/main.yml
test/integration/targets/handlers/roles/template_handler_names/tasks/evaluation_time.yml
test/integration/targets/handlers/roles/template_handler_names/tasks/lazy_evaluation.yml
test/integration/targets/handlers/roles/test_force_handlers/handlers/main.yml
test/integration/targets/handlers/roles/test_force_handlers/tasks/main.yml
test/integration/targets/handlers/roles/test_handlers/handlers/main.yml
test/integration/targets/handlers/roles/test_handlers/meta/main.yml
test/integration/targets/handlers/roles/test_handlers/tasks/main.yml
test/integration/targets/handlers/roles/test_handlers_include/handlers/main.yml
test/integration/targets/handlers/roles/test_handlers_include/tasks/main.yml
test/integration/targets/handlers/roles/test_handlers_include_role/handlers/main.yml
test/integration/targets/handlers/roles/test_handlers_include_role/meta/main.yml
test/integration/targets/handlers/roles/test_handlers_include_role/tasks/main.yml
test/integration/targets/handlers/roles/test_handlers_listen/handlers/main.yml
test/integration/targets/handlers/roles/test_handlers_listen/tasks/main.yml
test/integration/targets/handlers/roles/test_handlers_meta/handlers/alternate.yml
test/integration/targets/handlers/roles/test_handlers_meta/handlers/main.yml
test/integration/targets/handlers/roles/test_handlers_meta/tasks/main.yml
test/integration/targets/handlers/roles/test_listen_role_dedup_global/handlers/main.yml
test/integration/targets/handlers/roles/test_listen_role_dedup_role1/meta/main.yml
test/integration/targets/handlers/roles/test_listen_role_dedup_role1/tasks/main.yml
test/integration/targets/handlers/roles/test_listen_role_dedup_role2/meta/main.yml
test/integration/targets/handlers/roles/test_listen_role_dedup_role2/tasks/main.yml
test/integration/targets/handlers/roles/test_role_handlers_include_tasks/handlers/A.yml
test/integration/targets/handlers/roles/test_role_handlers_include_tasks/handlers/main.yml
test/integration/targets/handlers/roles/test_role_handlers_include_tasks/tasks/B.yml
test/integration/targets/handlers/roles/test_templating_in_handlers/handlers/main.yml
test/integration/targets/handlers/roles/test_templating_in_handlers/tasks/main.yml
test/integration/targets/handlers/roles/two_tasks_files_role/handlers/main.yml
test/integration/targets/handlers/roles/two_tasks_files_role/tasks/main.yml
test/integration/targets/handlers/roles/two_tasks_files_role/tasks/other.yml
test/integration/targets/hardware_facts/aliases
test/integration/targets/hardware_facts/meta/main.yml
test/integration/targets/hardware_facts/tasks/Linux.yml
test/integration/targets/hardware_facts/tasks/main.yml
test/integration/targets/hash/aliases
test/integration/targets/hash/runme.sh
test/integration/targets/hash/test_hash.yml
test/integration/targets/hash/test_inv1.yml
test/integration/targets/hash/test_inv2.yml
test/integration/targets/hash/test_inventory_hash.yml
test/integration/targets/hash/group_vars/all
test/integration/targets/hash/host_vars/testhost
test/integration/targets/hash/roles/test_hash_behaviour/defaults/main.yml
test/integration/targets/hash/roles/test_hash_behaviour/meta/main.yml
test/integration/targets/hash/roles/test_hash_behaviour/tasks/main.yml
test/integration/targets/hash/roles/test_hash_behaviour/vars/main.yml
test/integration/targets/hash/vars/test_hash_vars.yml
test/integration/targets/hostname/aliases
test/integration/targets/hostname/tasks/Debian.yml
test/integration/targets/hostname/tasks/MacOSX.yml
test/integration/targets/hostname/tasks/RedHat.yml
test/integration/targets/hostname/tasks/check_mode.yml
test/integration/targets/hostname/tasks/default.yml
test/integration/targets/hostname/tasks/main.yml
test/integration/targets/hostname/tasks/test_check_mode.yml
test/integration/targets/hostname/tasks/test_normal.yml
test/integration/targets/hostname/vars/FreeBSD.yml
test/integration/targets/hostname/vars/RedHat.yml
test/integration/targets/hostname/vars/default.yml
test/integration/targets/hosts_field/aliases
test/integration/targets/hosts_field/inventory.hosts_field
test/integration/targets/hosts_field/runme.sh
test/integration/targets/hosts_field/test_hosts_field.json
test/integration/targets/hosts_field/test_hosts_field.yml
test/integration/targets/ignore_errors/aliases
test/integration/targets/ignore_errors/runme.sh
test/integration/targets/ignore_errors/test_ignore_errors.yml
test/integration/targets/ignore_errors/test_ignore_errors_false.yml
test/integration/targets/ignore_errors/tasks/main.yml
test/integration/targets/ignore_unreachable/aliases
test/integration/targets/ignore_unreachable/inventory
test/integration/targets/ignore_unreachable/runme.sh
test/integration/targets/ignore_unreachable/test_base_cannot_connect.yml
test/integration/targets/ignore_unreachable/test_base_loop_cannot_connect.yml
test/integration/targets/ignore_unreachable/test_cannot_connect.yml
test/integration/targets/ignore_unreachable/test_with_bad_plugins.yml
test/integration/targets/ignore_unreachable/fake_connectors/bad_exec.py
test/integration/targets/ignore_unreachable/fake_connectors/bad_put_file.py
test/integration/targets/ignore_unreachable/meta/main.yml
test/integration/targets/import-role-tasks/aliases
test/integration/targets/import-role-tasks/import.yml
test/integration/targets/import-role-tasks/runme.sh
test/integration/targets/import-role-tasks/roles/test_environment/tasks/main.yml
test/integration/targets/import_tasks/aliases
test/integration/targets/import_tasks/inherit_notify.yml
test/integration/targets/import_tasks/runme.sh
test/integration/targets/import_tasks/tasks/trigger_change.yml
test/integration/targets/incidental_ios_file/aliases
test/integration/targets/incidental_ios_file/ios1.cfg
test/integration/targets/incidental_ios_file/nonascii.bin
test/integration/targets/incidental_ios_file/defaults/main.yaml
test/integration/targets/incidental_ios_file/tasks/cli.yaml
test/integration/targets/incidental_ios_file/tasks/main.yaml
test/integration/targets/incidental_ios_file/tests/cli/net_get.yaml
test/integration/targets/incidental_ios_file/tests/cli/net_put.yaml
test/integration/targets/incidental_win_reboot/aliases
test/integration/targets/incidental_win_reboot/tasks/main.yml
test/integration/targets/incidental_win_reboot/templates/post_reboot.ps1
test/integration/targets/include_import/aliases
test/integration/targets/include_import/inventory
test/integration/targets/include_import/issue73657.yml
test/integration/targets/include_import/issue73657_tasks.yml
test/integration/targets/include_import/runme.sh
test/integration/targets/include_import/test_copious_include_tasks.yml
test/integration/targets/include_import/test_copious_include_tasks_fqcn.yml
test/integration/targets/include_import/test_grandparent_inheritance.yml
test/integration/targets/include_import/test_grandparent_inheritance_fqcn.yml
test/integration/targets/include_import/test_include_loop.yml
test/integration/targets/include_import/test_include_loop_fqcn.yml
test/integration/targets/include_import/test_loop_var_bleed.yaml
test/integration/targets/include_import/test_nested_tasks.yml
test/integration/targets/include_import/test_nested_tasks_fqcn.yml
test/integration/targets/include_import/test_null_include_filename.yml
test/integration/targets/include_import/test_role_recursion.yml
test/integration/targets/include_import/test_role_recursion_fqcn.yml
test/integration/targets/include_import/apply/import_apply.yml
test/integration/targets/include_import/apply/include_apply.yml
test/integration/targets/include_import/apply/include_apply_65710.yml
test/integration/targets/include_import/apply/include_tasks.yml
test/integration/targets/include_import/apply/roles/include_role/tasks/main.yml
test/integration/targets/include_import/apply/roles/include_role2/tasks/main.yml
test/integration/targets/include_import/empty_group_warning/playbook.yml
test/integration/targets/include_import/empty_group_warning/tasks.yml
test/integration/targets/include_import/grandchild/block_include_tasks.yml
test/integration/targets/include_import/grandchild/import.yml
test/integration/targets/include_import/grandchild/import_include_include_tasks.yml
test/integration/targets/include_import/grandchild/include_level_1.yml
test/integration/targets/include_import/handler_addressing/playbook.yml
test/integration/targets/include_import/handler_addressing/roles/import_handler_test/handlers/main.yml
test/integration/targets/include_import/handler_addressing/roles/import_handler_test/tasks/handlers.yml
test/integration/targets/include_import/handler_addressing/roles/import_handler_test/tasks/main.yml
test/integration/targets/include_import/handler_addressing/roles/include_handler_test/handlers/main.yml
test/integration/targets/include_import/handler_addressing/roles/include_handler_test/tasks/handlers.yml
test/integration/targets/include_import/handler_addressing/roles/include_handler_test/tasks/main.yml
test/integration/targets/include_import/include_role_omit/playbook.yml
test/integration/targets/include_import/include_role_omit/roles/foo/tasks/main.yml
test/integration/targets/include_import/nestedtasks/nested/nested.yml
test/integration/targets/include_import/null_filename/tasks.yml
test/integration/targets/include_import/parent_templating/playbook.yml
test/integration/targets/include_import/parent_templating/roles/test/tasks/localhost.yml
test/integration/targets/include_import/parent_templating/roles/test/tasks/main.yml
test/integration/targets/include_import/parent_templating/roles/test/tasks/other.yml
test/integration/targets/include_import/playbook/playbook1.yml
test/integration/targets/include_import/playbook/playbook2.yml
test/integration/targets/include_import/playbook/playbook3.yml
test/integration/targets/include_import/playbook/playbook4.yml
test/integration/targets/include_import/playbook/playbook_needing_vars.yml
test/integration/targets/include_import/playbook/test_import_playbook.yml
test/integration/targets/include_import/playbook/test_import_playbook_tags.yml
test/integration/targets/include_import/playbook/test_templated_filenames.yml
test/integration/targets/include_import/playbook/validate1.yml
test/integration/targets/include_import/playbook/validate2.yml
test/integration/targets/include_import/playbook/validate34.yml
test/integration/targets/include_import/playbook/validate_tags.yml
test/integration/targets/include_import/playbook/validate_templated_playbook.yml
test/integration/targets/include_import/playbook/validate_templated_tasks.yml
test/integration/targets/include_import/playbook/group_vars/all.yml
test/integration/targets/include_import/playbook/roles/import_playbook_role/tasks/main.yml
test/integration/targets/include_import/playbook/sub_playbook/sub_playbook.yml
test/integration/targets/include_import/playbook/sub_playbook/library/helloworld.py
test/integration/targets/include_import/public_exposure/no_bleeding.yml
test/integration/targets/include_import/public_exposure/no_overwrite_roles.yml
test/integration/targets/include_import/public_exposure/playbook.yml
test/integration/targets/include_import/public_exposure/roles/call_import/tasks/main.yml
test/integration/targets/include_import/public_exposure/roles/dynamic/defaults/main.yml
test/integration/targets/include_import/public_exposure/roles/dynamic/tasks/main.yml
test/integration/targets/include_import/public_exposure/roles/dynamic/vars/main.yml
test/integration/targets/include_import/public_exposure/roles/dynamic_private/defaults/main.yml
test/integration/targets/include_import/public_exposure/roles/dynamic_private/tasks/main.yml
test/integration/targets/include_import/public_exposure/roles/dynamic_private/vars/main.yml
test/integration/targets/include_import/public_exposure/roles/from/defaults/from.yml
test/integration/targets/include_import/public_exposure/roles/from/tasks/from.yml
test/integration/targets/include_import/public_exposure/roles/from/vars/from.yml
test/integration/targets/include_import/public_exposure/roles/regular/defaults/main.yml
test/integration/targets/include_import/public_exposure/roles/regular/tasks/main.yml
test/integration/targets/include_import/public_exposure/roles/regular/vars/main.yml
test/integration/targets/include_import/public_exposure/roles/static/defaults/main.yml
test/integration/targets/include_import/public_exposure/roles/static/tasks/main.yml
test/integration/targets/include_import/public_exposure/roles/static/vars/main.yml
test/integration/targets/include_import/role/test_import_role.yml
test/integration/targets/include_import/role/test_include_role.yml
test/integration/targets/include_import/role/test_include_role_vars_from.yml
test/integration/targets/include_import/roles/delegated_handler/handlers/main.yml
test/integration/targets/include_import/roles/delegated_handler/tasks/main.yml
test/integration/targets/include_import/roles/dup_allowed_role/meta/main.yml
test/integration/targets/include_import/roles/dup_allowed_role/tasks/main.yml
test/integration/targets/include_import/roles/loop_name_assert/tasks/main.yml
test/integration/targets/include_import/roles/nested/nested/nested_dep_role2/defaults/main.yml
test/integration/targets/include_import/roles/nested/nested/nested_dep_role2/meta/main.yml
test/integration/targets/include_import/roles/nested/nested/nested_dep_role2/tasks/main.yml
test/integration/targets/include_import/roles/nested/nested/nested_dep_role2/tasks/rund.yml
test/integration/targets/include_import/roles/nested/nested/nested_dep_role2/vars/main.yml
test/integration/targets/include_import/roles/nested/nested/nested_dep_role2a/defaults/main.yml
test/integration/targets/include_import/roles/nested/nested/nested_dep_role2a/meta/main.yml
test/integration/targets/include_import/roles/nested/nested/nested_dep_role2a/tasks/main.yml
test/integration/targets/include_import/roles/nested/nested/nested_dep_role2a/tasks/rune.yml
test/integration/targets/include_import/roles/nested/nested/nested_dep_role2a/vars/main.yml
test/integration/targets/include_import/roles/nested/nested/nested_dep_role2b/defaults/main.yml
test/integration/targets/include_import/roles/nested/nested/nested_dep_role2b/meta/main.yml
test/integration/targets/include_import/roles/nested/nested/nested_dep_role2b/tasks/main.yml
test/integration/targets/include_import/roles/nested/nested/nested_dep_role2b/tasks/runf.yml
test/integration/targets/include_import/roles/nested/nested/nested_dep_role2b/vars/main.yml
test/integration/targets/include_import/roles/nested/nested_dep_role/defaults/main.yml
test/integration/targets/include_import/roles/nested/nested_dep_role/meta/main.yml
test/integration/targets/include_import/roles/nested/nested_dep_role/tasks/main.yml
test/integration/targets/include_import/roles/nested/nested_dep_role/tasks/runc.yml
test/integration/targets/include_import/roles/nested/nested_dep_role/vars/main.yml
test/integration/targets/include_import/roles/nested_include_task/meta/main.yml
test/integration/targets/include_import/roles/nested_include_task/tasks/main.yml
test/integration/targets/include_import/roles/nested_include_task/tasks/runa.yml
test/integration/targets/include_import/roles/role1/tasks/canary1.yml
test/integration/targets/include_import/roles/role1/tasks/canary2.yml
test/integration/targets/include_import/roles/role1/tasks/canary3.yml
test/integration/targets/include_import/roles/role1/tasks/fail.yml
test/integration/targets/include_import/roles/role1/tasks/main.yml
test/integration/targets/include_import/roles/role1/tasks/r1t01.yml
test/integration/targets/include_import/roles/role1/tasks/r1t02.yml
test/integration/targets/include_import/roles/role1/tasks/r1t03.yml
test/integration/targets/include_import/roles/role1/tasks/r1t04.yml
test/integration/targets/include_import/roles/role1/tasks/r1t05.yml
test/integration/targets/include_import/roles/role1/tasks/r1t06.yml
test/integration/targets/include_import/roles/role1/tasks/r1t07.yml
test/integration/targets/include_import/roles/role1/tasks/r1t08.yml
test/integration/targets/include_import/roles/role1/tasks/r1t09.yml
test/integration/targets/include_import/roles/role1/tasks/r1t10.yml
test/integration/targets/include_import/roles/role1/tasks/r1t11.yml
test/integration/targets/include_import/roles/role1/tasks/r1t12.yml
test/integration/targets/include_import/roles/role1/tasks/tasks.yml
test/integration/targets/include_import/roles/role1/tasks/templated.yml
test/integration/targets/include_import/roles/role1/tasks/vartest.yml
test/integration/targets/include_import/roles/role1/vars/main.yml
test/integration/targets/include_import/roles/role1/vars/role1vars.yml
test/integration/targets/include_import/roles/role2/tasks/main.yml
test/integration/targets/include_import/roles/role3/defaults/main.yml
test/integration/targets/include_import/roles/role3/handlers/main.yml
test/integration/targets/include_import/roles/role3/tasks/main.yml
test/integration/targets/include_import/roles/role3/tasks/tasks.yml
test/integration/targets/include_import/roles/role3/tasks/vartest.yml
test/integration/targets/include_import/roles/role3/vars/main.yml
test/integration/targets/include_import/roles/role3/vars/role3vars.yml
test/integration/targets/include_import/roles/role_with_argspec/meta/argument_specs.yml
test/integration/targets/include_import/roles/role_with_argspec/tasks/main.yml
test/integration/targets/include_import/roles/role_with_deps/meta/main.yml
test/integration/targets/include_import/roles/role_with_deps/tasks/main.yml
test/integration/targets/include_import/run_once/include_me.yml
test/integration/targets/include_import/run_once/playbook.yml
test/integration/targets/include_import/tasks/debug_item.yml
test/integration/targets/include_import/tasks/task_ansible_loop_index_var.yml
test/integration/targets/include_import/tasks/tasks1.yml
test/integration/targets/include_import/tasks/tasks2.yml
test/integration/targets/include_import/tasks/tasks3.yml
test/integration/targets/include_import/tasks/tasks4.yml
test/integration/targets/include_import/tasks/tasks5.yml
test/integration/targets/include_import/tasks/tasks6.yml
test/integration/targets/include_import/tasks/test_allow_single_role_dup.yml
test/integration/targets/include_import/tasks/test_dynamic_allow_dup.yml
test/integration/targets/include_import/tasks/test_import_tasks.yml
test/integration/targets/include_import/tasks/test_import_tasks_tags.yml
test/integration/targets/include_import/tasks/test_include_dupe_loop.yml
test/integration/targets/include_import/tasks/test_include_tasks.yml
test/integration/targets/include_import/tasks/test_include_tasks_tags.yml
test/integration/targets/include_import/tasks/test_recursion.yml
test/integration/targets/include_import/tasks/test_templating_IncludeRole_FA.yml
test/integration/targets/include_import/tasks/validate3.yml
test/integration/targets/include_import/tasks/validate_tags.yml
test/integration/targets/include_import/tasks/hello/.gitignore
test/integration/targets/include_import/tasks/hello/keep
test/integration/targets/include_import/tasks/nested/nested.yml
test/integration/targets/include_import/undefined_var/include_tasks.yml
test/integration/targets/include_import/undefined_var/include_that_defines_var.yml
test/integration/targets/include_import/undefined_var/playbook.yml
test/integration/targets/include_import/valid_include_keywords/include_me.yml
test/integration/targets/include_import/valid_include_keywords/include_me_listen.yml
test/integration/targets/include_import/valid_include_keywords/include_me_notify.yml
test/integration/targets/include_import/valid_include_keywords/playbook.yml
test/integration/targets/include_import_tasks_nested/aliases
test/integration/targets/include_import_tasks_nested/tasks/main.yml
test/integration/targets/include_import_tasks_nested/tasks/nested/nested_adjacent.yml
test/integration/targets/include_import_tasks_nested/tasks/nested/nested_import.yml
test/integration/targets/include_import_tasks_nested/tasks/nested/nested_include.yml
test/integration/targets/include_parent_role_vars/aliases
test/integration/targets/include_parent_role_vars/tasks/included_by_other_role.yml
test/integration/targets/include_parent_role_vars/tasks/included_by_ourselves.yml
test/integration/targets/include_parent_role_vars/tasks/main.yml
test/integration/targets/include_vars/aliases
test/integration/targets/include_vars/runme.sh
test/integration/targets/include_vars/test_as_playbook.yml
test/integration/targets/include_vars/test_as_role.yml
test/integration/targets/include_vars-ad-hoc/aliases
test/integration/targets/include_vars-ad-hoc/runme.sh
test/integration/targets/include_vars-ad-hoc/vaultpass
test/integration/targets/include_vars-ad-hoc/dir/encrypted.yml
test/integration/targets/include_vars-ad-hoc/dir/inc.yml
test/integration/targets/include_vars/defaults/main.yml
test/integration/targets/include_vars/files/test_depth/sub1/sub11.yml
test/integration/targets/include_vars/files/test_depth/sub1/sub12.yml
test/integration/targets/include_vars/files/test_depth/sub1/sub11/config11.yml
test/integration/targets/include_vars/files/test_depth/sub1/sub11/config112.yml
test/integration/targets/include_vars/files/test_depth/sub2/sub21.yml
test/integration/targets/include_vars/files/test_depth/sub2/sub21/config211.yml
test/integration/targets/include_vars/files/test_depth/sub2/sub21/config212.yml
test/integration/targets/include_vars/files/test_depth/sub3/config3.yml
test/integration/targets/include_vars/tasks/main.yml
test/integration/targets/include_vars/vars/no_auto_unsafe.yml
test/integration/targets/include_vars/vars/all/all.yml
test/integration/targets/include_vars/vars/environments/development/all.yml
test/integration/targets/include_vars/vars/environments/development/services/webapp.yml
test/integration/targets/include_vars/vars/services/service_vars.yml
test/integration/targets/include_vars/vars/services/service_vars_fqcn.yml
test/integration/targets/include_vars/vars/services/webapp.yml
test/integration/targets/include_vars/vars/webapp/file_without_extension
test/integration/targets/include_vars/vars2/hashes/hash1.yml
test/integration/targets/include_vars/vars2/hashes/hash2.yml
test/integration/targets/include_when_parent_is_dynamic/aliases
test/integration/targets/include_when_parent_is_dynamic/playbook.yml
test/integration/targets/include_when_parent_is_dynamic/runme.sh
test/integration/targets/include_when_parent_is_dynamic/syntax_error.yml
test/integration/targets/include_when_parent_is_dynamic/tasks.yml
test/integration/targets/include_when_parent_is_static/aliases
test/integration/targets/include_when_parent_is_static/playbook.yml
test/integration/targets/include_when_parent_is_static/runme.sh
test/integration/targets/include_when_parent_is_static/syntax_error.yml
test/integration/targets/include_when_parent_is_static/tasks.yml
test/integration/targets/includes/aliases
test/integration/targets/includes/include_on_playbook_should_fail.yml
test/integration/targets/includes/includes_loop_rescue.yml
test/integration/targets/includes/inherit_notify.yml
test/integration/targets/includes/runme.sh
test/integration/targets/includes/test_include_free.yml
test/integration/targets/includes/test_include_host_pinned.yml
test/integration/targets/includes/test_includes.yml
test/integration/targets/includes/test_includes2.yml
test/integration/targets/includes/test_includes3.yml
test/integration/targets/includes/test_includes4.yml
test/integration/targets/includes/roles/test_includes/handlers/main.yml
test/integration/targets/includes/roles/test_includes/handlers/more_handlers.yml
test/integration/targets/includes/roles/test_includes/tasks/branch_toplevel.yml
test/integration/targets/includes/roles/test_includes/tasks/empty.yml
test/integration/targets/includes/roles/test_includes/tasks/included_task1.yml
test/integration/targets/includes/roles/test_includes/tasks/leaf_sublevel.yml
test/integration/targets/includes/roles/test_includes/tasks/main.yml
test/integration/targets/includes/roles/test_includes/tasks/not_a_role_task.yml
test/integration/targets/includes/roles/test_includes_free/tasks/inner.yml
test/integration/targets/includes/roles/test_includes_free/tasks/inner_fqcn.yml
test/integration/targets/includes/roles/test_includes_free/tasks/main.yml
test/integration/targets/includes/roles/test_includes_host_pinned/tasks/inner.yml
test/integration/targets/includes/roles/test_includes_host_pinned/tasks/main.yml
test/integration/targets/includes/tasks/trigger_change.yml
test/integration/targets/includes_race/aliases
test/integration/targets/includes_race/inventory
test/integration/targets/includes_race/runme.sh
test/integration/targets/includes_race/test_includes_race.yml
test/integration/targets/includes_race/roles/random_sleep/tasks/main.yml
test/integration/targets/includes_race/roles/set_a_fact/tasks/fact1.yml
test/integration/targets/includes_race/roles/set_a_fact/tasks/fact2.yml
test/integration/targets/infra/aliases
test/integration/targets/infra/inventory.local
test/integration/targets/infra/runme.sh
test/integration/targets/infra/test_test_infra.yml
test/integration/targets/infra/library/test.py
test/integration/targets/interpreter_discovery_python/aliases
test/integration/targets/interpreter_discovery_python/bad-connection.yml
test/integration/targets/interpreter_discovery_python/discovery.yml
test/integration/targets/interpreter_discovery_python/runme.sh
test/integration/targets/interpreter_discovery_python/library/test_echo_module.py
test/integration/targets/interpreter_discovery_python/library/test_non_python_interpreter.py
test/integration/targets/interpreter_discovery_python/tasks/config_templating.yml
test/integration/targets/interpreter_discovery_python/tasks/main.yml
test/integration/targets/interpreter_discovery_python_delegate_facts/aliases
test/integration/targets/interpreter_discovery_python_delegate_facts/delegate_facts.yml
test/integration/targets/interpreter_discovery_python_delegate_facts/inventory
test/integration/targets/interpreter_discovery_python_delegate_facts/runme.sh
test/integration/targets/inventory/aliases
test/integration/targets/inventory/extra_vars_constructed.yml
test/integration/targets/inventory/host_vars_constructed.yml
test/integration/targets/inventory/inv_with_host_vars.yml
test/integration/targets/inventory/inv_with_int.yml
test/integration/targets/inventory/playbook.yml
test/integration/targets/inventory/runme.sh
test/integration/targets/inventory/strategy.yml
test/integration/targets/inventory/test_empty.yml
test/integration/targets/inventory-invalid-group/aliases
test/integration/targets/inventory-invalid-group/inventory.ini
test/integration/targets/inventory-invalid-group/runme.sh
test/integration/targets/inventory-invalid-group/test.yml
test/integration/targets/inventory/1/vars.yml
test/integration/targets/inventory/1/2/inventory.yml
test/integration/targets/inventory/1/2/3/extra_vars_relative.yml
test/integration/targets/inventory/doc_fragments/fragment_with_expression.py
test/integration/targets/inventory/inventory_plugins/constructed_with_hostvars.py
test/integration/targets/inventory_advanced_host_list/aliases
test/integration/targets/inventory_advanced_host_list/runme.sh
test/integration/targets/inventory_advanced_host_list/test_advanced_host_list.yml
test/integration/targets/inventory_cache/aliases
test/integration/targets/inventory_cache/cache_host.yml
test/integration/targets/inventory_cache/exercise_cache.yml
test/integration/targets/inventory_cache/runme.sh
test/integration/targets/inventory_cache/cache/.keep
test/integration/targets/inventory_cache/plugins/inventory/cache_host.py
test/integration/targets/inventory_cache/plugins/inventory/exercise_cache.py
test/integration/targets/inventory_constructed/aliases
test/integration/targets/inventory_constructed/constructed.yml
test/integration/targets/inventory_constructed/keyed_group_default_value.yml
test/integration/targets/inventory_constructed/keyed_group_list_default_value.yml
test/integration/targets/inventory_constructed/keyed_group_str_default_value.yml
test/integration/targets/inventory_constructed/keyed_group_trailing_separator.yml
test/integration/targets/inventory_constructed/no_leading_separator_constructed.yml
test/integration/targets/inventory_constructed/runme.sh
test/integration/targets/inventory_constructed/static_inventory.yml
test/integration/targets/inventory_constructed/tag_inventory.yml
test/integration/targets/inventory_constructed/invs/1/one.yml
test/integration/targets/inventory_constructed/invs/1/group_vars/stuff.yml
test/integration/targets/inventory_constructed/invs/1/host_vars/testing.yml
test/integration/targets/inventory_constructed/invs/2/constructed.yml
test/integration/targets/inventory_generator/aliases
test/integration/targets/inventory_generator/generator.yml
test/integration/targets/inventory_generator/parent_without_name.yml
test/integration/targets/inventory_generator/runme.sh
test/integration/targets/inventory_generator/verify.yml
test/integration/targets/inventory_ini/aliases
test/integration/targets/inventory_ini/inventory.ini
test/integration/targets/inventory_ini/runme.sh
test/integration/targets/inventory_ini/test_ansible_become.yml
test/integration/targets/inventory_ini/test_types.yml
test/integration/targets/inventory_script/aliases
test/integration/targets/inventory_script/bad_shebang
test/integration/targets/inventory_script/script_inventory_fixture.py
test/integration/targets/inventory_script/tasks/main.yml
test/integration/targets/inventory_script/tasks/test_broken_inventory.yml
test/integration/targets/inventory_script/tasks/test_valid_inventory.yml
test/integration/targets/inventory_toml/aliases
test/integration/targets/inventory_toml/inventory.toml
test/integration/targets/inventory_toml/playbook.yml
test/integration/targets/inventory_toml/runme.sh
test/integration/targets/inventory_yaml/aliases
test/integration/targets/inventory_yaml/empty.json
test/integration/targets/inventory_yaml/runme.sh
test/integration/targets/inventory_yaml/success.json
test/integration/targets/inventory_yaml/test.yml
test/integration/targets/inventory_yaml/test_int_hostname.yml
test/integration/targets/iptables/aliases
test/integration/targets/iptables/tasks/chain_management.yml
test/integration/targets/iptables/tasks/main.yml
test/integration/targets/iptables/vars/alpine.yml
test/integration/targets/iptables/vars/centos.yml
test/integration/targets/iptables/vars/default.yml
test/integration/targets/iptables/vars/fedora.yml
test/integration/targets/iptables/vars/redhat.yml
test/integration/targets/iptables/vars/suse.yml
test/integration/targets/jinja2_native_types/aliases
test/integration/targets/jinja2_native_types/nested_undefined.yml
test/integration/targets/jinja2_native_types/runme.sh
test/integration/targets/jinja2_native_types/runtests.yml
test/integration/targets/jinja2_native_types/test_bool.yml
test/integration/targets/jinja2_native_types/test_casting.yml
test/integration/targets/jinja2_native_types/test_concatentation.yml
test/integration/targets/jinja2_native_types/test_hostvars.yml
test/integration/targets/jinja2_native_types/test_none.yml
test/integration/targets/jinja2_native_types/test_preserving_quotes.yml
test/integration/targets/jinja2_native_types/test_template.yml
test/integration/targets/jinja2_native_types/test_template_newlines.j2
test/integration/targets/jinja2_native_types/test_types.yml
test/integration/targets/jinja2_native_types/test_vault.yml
test/integration/targets/jinja2_native_types/test_vault_pass
test/integration/targets/jinja_plugins/aliases
test/integration/targets/jinja_plugins/playbook.yml
test/integration/targets/jinja_plugins/collections/ansible_collections/foo/bar/plugins/filter/bad_collection_filter.py
test/integration/targets/jinja_plugins/collections/ansible_collections/foo/bar/plugins/filter/bad_collection_filter2.py
test/integration/targets/jinja_plugins/collections/ansible_collections/foo/bar/plugins/filter/good_collection_filter.py
test/integration/targets/jinja_plugins/collections/ansible_collections/foo/bar/plugins/test/bad_collection_test.py
test/integration/targets/jinja_plugins/collections/ansible_collections/foo/bar/plugins/test/good_collection_test.py
test/integration/targets/jinja_plugins/filter_plugins/bad_filter.py
test/integration/targets/jinja_plugins/filter_plugins/good_filter.py
test/integration/targets/jinja_plugins/tasks/main.yml
test/integration/targets/jinja_plugins/test_plugins/bad_test.py
test/integration/targets/jinja_plugins/test_plugins/good_test.py
test/integration/targets/json-serialization/aliases
test/integration/targets/json-serialization/runme.sh
test/integration/targets/json-serialization/test.yml
test/integration/targets/json_cleanup/aliases
test/integration/targets/json_cleanup/module_output_cleaning.yml
test/integration/targets/json_cleanup/runme.sh
test/integration/targets/json_cleanup/library/bad_json
test/integration/targets/keyword_inheritance/aliases
test/integration/targets/keyword_inheritance/dep_keyword_inheritance.yml
test/integration/targets/keyword_inheritance/runme.sh
test/integration/targets/keyword_inheritance/test.yml
test/integration/targets/keyword_inheritance/roles/role-meta-inheritance/meta/main.yml
test/integration/targets/keyword_inheritance/roles/whoami/tasks/main.yml
test/integration/targets/known_hosts/aliases
test/integration/targets/known_hosts/defaults/main.yml
test/integration/targets/known_hosts/files/existing_known_hosts
test/integration/targets/known_hosts/meta/main.yml
test/integration/targets/known_hosts/tasks/main.yml
test/integration/targets/limit_inventory/aliases
test/integration/targets/limit_inventory/hosts.yml
test/integration/targets/limit_inventory/runme.sh
test/integration/targets/lineinfile/aliases
test/integration/targets/lineinfile/files/firstmatch.txt
test/integration/targets/lineinfile/files/test.conf
test/integration/targets/lineinfile/files/test.txt
test/integration/targets/lineinfile/files/test_58923.txt
test/integration/targets/lineinfile/files/testempty.txt
test/integration/targets/lineinfile/files/testmultiple.txt
test/integration/targets/lineinfile/files/testnoeof.txt
test/integration/targets/lineinfile/files/teststring.conf
test/integration/targets/lineinfile/files/teststring.txt
test/integration/targets/lineinfile/files/teststring_58923.txt
test/integration/targets/lineinfile/meta/main.yml
test/integration/targets/lineinfile/tasks/acls.yml
test/integration/targets/lineinfile/tasks/main.yml
test/integration/targets/lineinfile/tasks/test_string01.yml
test/integration/targets/lineinfile/tasks/test_string02.yml
test/integration/targets/lineinfile/vars/main.yml
test/integration/targets/lookup-option-name/aliases
test/integration/targets/lookup-option-name/lookup_plugins/non_terms_posargs.py
test/integration/targets/lookup-option-name/tasks/main.yml
test/integration/targets/lookup_config/aliases
test/integration/targets/lookup_config/runme.sh
test/integration/targets/lookup_config/runme.yml
test/integration/targets/lookup_config/lookup_plugins/bogus.py
test/integration/targets/lookup_config/tasks/main.yml
test/integration/targets/lookup_csvfile/aliases
test/integration/targets/lookup_csvfile/files/cool list of things.csv
test/integration/targets/lookup_csvfile/files/crlf.csv
test/integration/targets/lookup_csvfile/files/people.csv
test/integration/targets/lookup_csvfile/files/tabs.csv
test/integration/targets/lookup_csvfile/files/x1a.csv
test/integration/targets/lookup_csvfile/tasks/main.yml
test/integration/targets/lookup_dict/aliases
test/integration/targets/lookup_dict/tasks/main.yml
test/integration/targets/lookup_env/aliases
test/integration/targets/lookup_env/runme.sh
test/integration/targets/lookup_env/vars_not_set.yml
test/integration/targets/lookup_env/vars_set.yml
test/integration/targets/lookup_file/aliases
test/integration/targets/lookup_file/tasks/main.yml
test/integration/targets/lookup_fileglob/aliases
test/integration/targets/lookup_fileglob/runme.sh
test/integration/targets/lookup_fileglob/find_levels/play.yml
test/integration/targets/lookup_fileglob/find_levels/play_adj.txt
test/integration/targets/lookup_fileglob/find_levels/files/play_adj_subdir.txt
test/integration/targets/lookup_fileglob/find_levels/files/somepath/play_adj_subsubdir.txt
test/integration/targets/lookup_fileglob/find_levels/roles/get_file/files/in_role.txt
test/integration/targets/lookup_fileglob/find_levels/roles/get_file/files/otherpath/in_role_subdir.txt
test/integration/targets/lookup_fileglob/find_levels/roles/get_file/tasks/main.yml
test/integration/targets/lookup_fileglob/issue72873/test.yml
test/integration/targets/lookup_fileglob/non_existent/play.yml
test/integration/targets/lookup_first_found/aliases
test/integration/targets/lookup_first_found/action_plugins/debug_file_alias.py
test/integration/targets/lookup_first_found/action_plugins/debug_template_alias.py
test/integration/targets/lookup_first_found/action_plugins/debug_var_alias.py
test/integration/targets/lookup_first_found/files/bar1
test/integration/targets/lookup_first_found/files/findme.txt
test/integration/targets/lookup_first_found/files/foo1
test/integration/targets/lookup_first_found/files/vars file spaces.yml
test/integration/targets/lookup_first_found/roles/a/tasks/main.yml
test/integration/targets/lookup_first_found/roles/a/tasks/subdir/main.yml
test/integration/targets/lookup_first_found/roles/a/tasks/subdir/relative
test/integration/targets/lookup_first_found/tasks/main.yml
test/integration/targets/lookup_first_found/templates/findme.txt
test/integration/targets/lookup_first_found/vars/findme.txt
test/integration/targets/lookup_first_found/vars/ishouldnotbefound.yml
test/integration/targets/lookup_first_found/vars/itworks.yml
test/integration/targets/lookup_indexed_items/aliases
test/integration/targets/lookup_indexed_items/tasks/main.yml
test/integration/targets/lookup_ini/aliases
test/integration/targets/lookup_ini/duplicate.ini
test/integration/targets/lookup_ini/duplicate_case_check.ini
test/integration/targets/lookup_ini/interpolation.ini
test/integration/targets/lookup_ini/inventory
test/integration/targets/lookup_ini/lookup-8859-15.ini
test/integration/targets/lookup_ini/lookup.ini
test/integration/targets/lookup_ini/lookup.properties
test/integration/targets/lookup_ini/lookup_case_check.properties
test/integration/targets/lookup_ini/mysql.ini
test/integration/targets/lookup_ini/nointerpolation.ini
test/integration/targets/lookup_ini/runme.sh
test/integration/targets/lookup_ini/test_allow_no_value.yml
test/integration/targets/lookup_ini/test_case_sensitive.yml
test/integration/targets/lookup_ini/test_errors.yml
test/integration/targets/lookup_ini/test_ini.yml
test/integration/targets/lookup_ini/test_interpolation.yml
test/integration/targets/lookup_ini/test_lookup_properties.yml
test/integration/targets/lookup_inventory_hostnames/aliases
test/integration/targets/lookup_inventory_hostnames/inventory
test/integration/targets/lookup_inventory_hostnames/main.yml
test/integration/targets/lookup_inventory_hostnames/runme.sh
test/integration/targets/lookup_items/aliases
test/integration/targets/lookup_items/tasks/main.yml
test/integration/targets/lookup_lines/aliases
test/integration/targets/lookup_lines/tasks/main.yml
test/integration/targets/lookup_list/aliases
test/integration/targets/lookup_list/tasks/main.yml
test/integration/targets/lookup_nested/aliases
test/integration/targets/lookup_nested/tasks/main.yml
test/integration/targets/lookup_password/aliases
test/integration/targets/lookup_password/runme.sh
test/integration/targets/lookup_password/runme.yml
test/integration/targets/lookup_password/tasks/main.yml
test/integration/targets/lookup_pipe/aliases
test/integration/targets/lookup_pipe/tasks/main.yml
test/integration/targets/lookup_random_choice/aliases
test/integration/targets/lookup_random_choice/tasks/main.yml
test/integration/targets/lookup_sequence/aliases
test/integration/targets/lookup_sequence/tasks/main.yml
test/integration/targets/lookup_subelements/aliases
test/integration/targets/lookup_subelements/tasks/main.yml
test/integration/targets/lookup_subelements/vars/main.yml
test/integration/targets/lookup_template/aliases
test/integration/targets/lookup_template/files/trim_blocks_false.expected
test/integration/targets/lookup_template/files/trim_blocks_true.expected
test/integration/targets/lookup_template/tasks/main.yml
test/integration/targets/lookup_template/tasks/trim_blocks.yml
test/integration/targets/lookup_template/templates/dict.j2
test/integration/targets/lookup_template/templates/hello.txt
test/integration/targets/lookup_template/templates/hello_comment.txt
test/integration/targets/lookup_template/templates/hello_string.txt
test/integration/targets/lookup_template/templates/none.j2
test/integration/targets/lookup_template/templates/trim_blocks.j2
test/integration/targets/lookup_template/templates/world.txt
test/integration/targets/lookup_together/aliases
test/integration/targets/lookup_together/tasks/main.yml
test/integration/targets/lookup_unvault/aliases
test/integration/targets/lookup_unvault/runme.sh
test/integration/targets/lookup_unvault/secret
test/integration/targets/lookup_unvault/unvault.yml
test/integration/targets/lookup_unvault/files/foot.txt
test/integration/targets/lookup_unvault/files/foot.txt.vault
test/integration/targets/lookup_url/aliases
test/integration/targets/lookup_url/meta/main.yml
test/integration/targets/lookup_url/tasks/ciphers.yml
test/integration/targets/lookup_url/tasks/main.yml
test/integration/targets/lookup_url/tasks/use_netrc.yml
test/integration/targets/lookup_varnames/aliases
test/integration/targets/lookup_varnames/tasks/main.yml
test/integration/targets/lookup_vars/aliases
test/integration/targets/lookup_vars/tasks/main.yml
test/integration/targets/loop-connection/aliases
test/integration/targets/loop-connection/main.yml
test/integration/targets/loop-connection/runme.sh
test/integration/targets/loop-connection/collections/ansible_collections/ns/name/meta/runtime.yml
test/integration/targets/loop-connection/collections/ansible_collections/ns/name/plugins/connection/dummy.py
test/integration/targets/loop-until/aliases
test/integration/targets/loop-until/tasks/main.yml
test/integration/targets/loop_control/aliases
test/integration/targets/loop_control/break_when.yml
test/integration/targets/loop_control/extended.yml
test/integration/targets/loop_control/inner.yml
test/integration/targets/loop_control/label.yml
test/integration/targets/loop_control/runme.sh
test/integration/targets/loops/aliases
test/integration/targets/loops/files/data1.txt
test/integration/targets/loops/files/data2.txt
test/integration/targets/loops/tasks/index_var_tasks.yml
test/integration/targets/loops/tasks/main.yml
test/integration/targets/loops/tasks/templated_loop_var_tasks.yml
test/integration/targets/loops/vars/main.yml
test/integration/targets/meta_tasks/aliases
test/integration/targets/meta_tasks/inventory.yml
test/integration/targets/meta_tasks/inventory_new.yml
test/integration/targets/meta_tasks/inventory_old.yml
test/integration/targets/meta_tasks/inventory_refresh.yml
test/integration/targets/meta_tasks/refresh.yml
test/integration/targets/meta_tasks/refresh_preserve_dynamic.yml
test/integration/targets/meta_tasks/runme.sh
test/integration/targets/meta_tasks/test_end_batch.yml
test/integration/targets/meta_tasks/test_end_host.yml
test/integration/targets/meta_tasks/test_end_host_all.yml
test/integration/targets/meta_tasks/test_end_host_all_fqcn.yml
test/integration/targets/meta_tasks/test_end_host_fqcn.yml
test/integration/targets/meta_tasks/test_end_host_rescue_rc.yml
test/integration/targets/meta_tasks/test_end_play.yml
test/integration/targets/meta_tasks/test_end_play_fqcn.yml
test/integration/targets/meta_tasks/test_end_play_multiple_plays.yml
test/integration/targets/meta_tasks/test_end_play_serial_one.yml
test/integration/targets/missing-interpreter/aliases
test/integration/targets/missing-interpreter/tasks/main.yml
test/integration/targets/missing_required_lib/aliases
test/integration/targets/missing_required_lib/runme.sh
test/integration/targets/missing_required_lib/runme.yml
test/integration/targets/missing_required_lib/library/missing_required_lib.py
test/integration/targets/missing_required_lib/tasks/main.yml
test/integration/targets/module-serialization-profiles/aliases
test/integration/targets/module-serialization-profiles/library/echo_legacy.py
test/integration/targets/module-serialization-profiles/library/echo_modern.py
test/integration/targets/module-serialization-profiles/library/echo_unspecified.py
test/integration/targets/module-serialization-profiles/tasks/main.yml
test/integration/targets/module-serialization-profiles/vars/main.yml
test/integration/targets/module_defaults/aliases
test/integration/targets/module_defaults/runme.sh
test/integration/targets/module_defaults/test_action_group_metadata.yml
test/integration/targets/module_defaults/test_action_groups.yml
test/integration/targets/module_defaults/test_defaults.yml
test/integration/targets/module_defaults/test_templated_defaults.yml
test/integration/targets/module_defaults/action_plugins/debug.py
test/integration/targets/module_defaults/collections/ansible_collections/testns/othercoll/plugins/action/other_echoaction.py
test/integration/targets/module_defaults/collections/ansible_collections/testns/othercoll/plugins/modules/other_echo1.py
test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/meta/runtime.yml
test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/action/echoaction.py
test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/action/eos.py
test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/action/ios.py
test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/action/vyos.py
test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/module_utils/echo_impl.py
test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/echo1.py
test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/echo2.py
test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/eosfacts.py
test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/ios_facts.py
test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/metadata.py
test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/module.py
test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/ping.py
test/integration/targets/module_defaults/collections/ansible_collections/testns/testcoll/plugins/modules/vyosfacts.py
test/integration/targets/module_defaults/library/legacy_ping.py
test/integration/targets/module_defaults/library/test_module_defaults.py
test/integration/targets/module_defaults/tasks/main.yml
test/integration/targets/module_defaults/templates/test_metadata_warning.yml.j2
test/integration/targets/module_no_log/aliases
test/integration/targets/module_no_log/library/module_that_has_secret.py
test/integration/targets/module_no_log/library/module_that_logs.py
test/integration/targets/module_no_log/tasks/main.yml
test/integration/targets/module_precedence/aliases
test/integration/targets/module_precedence/modules_test.yml
test/integration/targets/module_precedence/modules_test_envvar.yml
test/integration/targets/module_precedence/modules_test_envvar_ext.yml
test/integration/targets/module_precedence/modules_test_multiple_roles.yml
test/integration/targets/module_precedence/modules_test_multiple_roles_reverse_order.yml
test/integration/targets/module_precedence/modules_test_role.yml
test/integration/targets/module_precedence/modules_test_role_ext.yml
test/integration/targets/module_precedence/runme.sh
test/integration/targets/module_precedence/lib_no_extension/ping
test/integration/targets/module_precedence/lib_with_extension/a.ini
test/integration/targets/module_precedence/lib_with_extension/a.py
test/integration/targets/module_precedence/lib_with_extension/ping.ini
test/integration/targets/module_precedence/lib_with_extension/ping.py
test/integration/targets/module_precedence/multiple_roles/bar/library/ping.py
test/integration/targets/module_precedence/multiple_roles/bar/tasks/main.yml
test/integration/targets/module_precedence/multiple_roles/foo/library/ping.py
test/integration/targets/module_precedence/multiple_roles/foo/tasks/main.yml
test/integration/targets/module_precedence/roles_no_extension/foo/library/ping
test/integration/targets/module_precedence/roles_no_extension/foo/tasks/main.yml
test/integration/targets/module_precedence/roles_with_extension/foo/library/a.ini
test/integration/targets/module_precedence/roles_with_extension/foo/library/a.py
test/integration/targets/module_precedence/roles_with_extension/foo/library/ping.ini
test/integration/targets/module_precedence/roles_with_extension/foo/library/ping.py
test/integration/targets/module_precedence/roles_with_extension/foo/tasks/main.yml
test/integration/targets/module_tracebacks/aliases
test/integration/targets/module_tracebacks/inventory
test/integration/targets/module_tracebacks/runme.sh
test/integration/targets/module_tracebacks/traceback.yml
test/integration/targets/module_tracebacks/library/ansibull.py
test/integration/targets/module_utils/aliases
test/integration/targets/module_utils/module_utils_basic_setcwd.yml
test/integration/targets/module_utils/module_utils_common_dict_transformation.yml
test/integration/targets/module_utils/module_utils_common_network.yml
test/integration/targets/module_utils/module_utils_envvar.yml
test/integration/targets/module_utils/module_utils_test.yml
test/integration/targets/module_utils/module_utils_test_no_log.yml
test/integration/targets/module_utils/module_utils_vvvvv.yml
test/integration/targets/module_utils/runme.sh
test/integration/targets/module_utils/callback/pure_json.py
test/integration/targets/module_utils/collections/ansible_collections/testns/testcoll/plugins/module_utils/legit.py
test/integration/targets/module_utils/library/test.py
test/integration/targets/module_utils/library/test_alias_deprecation.py
test/integration/targets/module_utils/library/test_cwd_missing.py
test/integration/targets/module_utils/library/test_cwd_unreadable.py
test/integration/targets/module_utils/library/test_datetime.py
test/integration/targets/module_utils/library/test_env_override.py
test/integration/targets/module_utils/library/test_failure.py
test/integration/targets/module_utils/library/test_heuristic_log_sanitize.py
test/integration/targets/module_utils/library/test_network.py
test/integration/targets/module_utils/library/test_no_log.py
test/integration/targets/module_utils/library/test_optional.py
test/integration/targets/module_utils/library/test_override.py
test/integration/targets/module_utils/library/test_recursive_diff.py
test/integration/targets/module_utils/module_utils/__init__.py
test/integration/targets/module_utils/module_utils/ansible_release.py
test/integration/targets/module_utils/module_utils/foo0.py
test/integration/targets/module_utils/module_utils/foo1.py
test/integration/targets/module_utils/module_utils/foo2.py
test/integration/targets/module_utils/module_utils/service.py
test/integration/targets/module_utils/module_utils/a/__init__.py
test/integration/targets/module_utils/module_utils/a/b/__init__.py
test/integration/targets/module_utils/module_utils/a/b/c/__init__.py
test/integration/targets/module_utils/module_utils/a/b/c/d/__init__.py
test/integration/targets/module_utils/module_utils/a/b/c/d/e/__init__.py
test/integration/targets/module_utils/module_utils/a/b/c/d/e/f/__init__.py
test/integration/targets/module_utils/module_utils/a/b/c/d/e/f/g/__init__.py
test/integration/targets/module_utils/module_utils/a/b/c/d/e/f/g/h/__init__.py
test/integration/targets/module_utils/module_utils/bar0/__init__.py
test/integration/targets/module_utils/module_utils/bar0/foo3.py
test/integration/targets/module_utils/module_utils/bar1/__init__.py
test/integration/targets/module_utils/module_utils/bar2/__init__.py
test/integration/targets/module_utils/module_utils/baz1/__init__.py
test/integration/targets/module_utils/module_utils/baz1/one.py
test/integration/targets/module_utils/module_utils/baz2/__init__.py
test/integration/targets/module_utils/module_utils/baz2/one.py
test/integration/targets/module_utils/module_utils/qux1/__init__.py
test/integration/targets/module_utils/module_utils/qux1/quux.py
test/integration/targets/module_utils/module_utils/qux2/__init__.py
test/integration/targets/module_utils/module_utils/qux2/quux.py
test/integration/targets/module_utils/module_utils/qux2/quuz.py
test/integration/targets/module_utils/module_utils/spam1/__init__.py
test/integration/targets/module_utils/module_utils/spam1/ham/__init__.py
test/integration/targets/module_utils/module_utils/spam1/ham/eggs/__init__.py
test/integration/targets/module_utils/module_utils/spam2/__init__.py
test/integration/targets/module_utils/module_utils/spam2/ham/__init__.py
test/integration/targets/module_utils/module_utils/spam2/ham/eggs/__init__.py
test/integration/targets/module_utils/module_utils/spam3/__init__.py
test/integration/targets/module_utils/module_utils/spam3/ham/__init__.py
test/integration/targets/module_utils/module_utils/spam3/ham/bacon.py
test/integration/targets/module_utils/module_utils/spam4/__init__.py
test/integration/targets/module_utils/module_utils/spam4/ham/__init__.py
test/integration/targets/module_utils/module_utils/spam4/ham/bacon.py
test/integration/targets/module_utils/module_utils/spam5/__init__.py
test/integration/targets/module_utils/module_utils/spam5/ham/__init__.py
test/integration/targets/module_utils/module_utils/spam5/ham/bacon.py
test/integration/targets/module_utils/module_utils/spam5/ham/eggs.py
test/integration/targets/module_utils/module_utils/spam6/__init__.py
test/integration/targets/module_utils/module_utils/spam6/ham/__init__.py
test/integration/targets/module_utils/module_utils/spam7/__init__.py
test/integration/targets/module_utils/module_utils/spam7/ham/__init__.py
test/integration/targets/module_utils/module_utils/spam7/ham/bacon.py
test/integration/targets/module_utils/module_utils/spam8/__init__.py
test/integration/targets/module_utils/module_utils/spam8/ham/__init__.py
test/integration/targets/module_utils/module_utils/spam8/ham/bacon.py
test/integration/targets/module_utils/module_utils/sub/__init__.py
test/integration/targets/module_utils/module_utils/sub/bam.py
test/integration/targets/module_utils/module_utils/sub/bam/__init__.py
test/integration/targets/module_utils/module_utils/sub/bam/bam.py
test/integration/targets/module_utils/module_utils/yak/__init__.py
test/integration/targets/module_utils/module_utils/yak/zebra/__init__.py
test/integration/targets/module_utils/module_utils/yak/zebra/foo4.py
test/integration/targets/module_utils/other_mu_dir/__init__.py
test/integration/targets/module_utils/other_mu_dir/facts.py
test/integration/targets/module_utils/other_mu_dir/json_utils.py
test/integration/targets/module_utils/other_mu_dir/mork.py
test/integration/targets/module_utils/other_mu_dir/a/__init__.py
test/integration/targets/module_utils/other_mu_dir/a/b/__init__.py
test/integration/targets/module_utils/other_mu_dir/a/b/c/__init__.py
test/integration/targets/module_utils/other_mu_dir/a/b/c/d/__init__.py
test/integration/targets/module_utils/other_mu_dir/a/b/c/d/e/__init__.py
test/integration/targets/module_utils/other_mu_dir/a/b/c/d/e/f/__init__.py
test/integration/targets/module_utils/other_mu_dir/a/b/c/d/e/f/g/__init__.py
test/integration/targets/module_utils/other_mu_dir/a/b/c/d/e/f/g/h/__init__.py
test/integration/targets/module_utils_Ansible.AccessToken/aliases
test/integration/targets/module_utils_Ansible.AccessToken/library/ansible_access_token_tests.ps1
test/integration/targets/module_utils_Ansible.AccessToken/tasks/main.yml
test/integration/targets/module_utils_Ansible.Basic/aliases
test/integration/targets/module_utils_Ansible.Basic/library/ansible_basic_tests.ps1
test/integration/targets/module_utils_Ansible.Basic/tasks/main.yml
test/integration/targets/module_utils_Ansible.Become/aliases
test/integration/targets/module_utils_Ansible.Become/library/ansible_become_tests.ps1
test/integration/targets/module_utils_Ansible.Become/tasks/main.yml
test/integration/targets/module_utils_Ansible.ModuleUtils.AddType/aliases
test/integration/targets/module_utils_Ansible.ModuleUtils.AddType/library/add_type_test.ps1
test/integration/targets/module_utils_Ansible.ModuleUtils.AddType/tasks/main.yml
test/integration/targets/module_utils_Ansible.ModuleUtils.ArgvParser/aliases
test/integration/targets/module_utils_Ansible.ModuleUtils.ArgvParser/library/argv_parser_test.ps1
test/integration/targets/module_utils_Ansible.ModuleUtils.ArgvParser/meta/main.yml
test/integration/targets/module_utils_Ansible.ModuleUtils.ArgvParser/tasks/main.yml
test/integration/targets/module_utils_Ansible.ModuleUtils.Backup/aliases
test/integration/targets/module_utils_Ansible.ModuleUtils.Backup/library/backup_file_test.ps1
test/integration/targets/module_utils_Ansible.ModuleUtils.Backup/tasks/main.yml
test/integration/targets/module_utils_Ansible.ModuleUtils.CamelConversion/aliases
test/integration/targets/module_utils_Ansible.ModuleUtils.CamelConversion/library/camel_conversion_test.ps1
test/integration/targets/module_utils_Ansible.ModuleUtils.CamelConversion/tasks/main.yml
test/integration/targets/module_utils_Ansible.ModuleUtils.CommandUtil/aliases
test/integration/targets/module_utils_Ansible.ModuleUtils.CommandUtil/library/command_util_test.ps1
test/integration/targets/module_utils_Ansible.ModuleUtils.CommandUtil/meta/main.yml
test/integration/targets/module_utils_Ansible.ModuleUtils.CommandUtil/tasks/main.yml
test/integration/targets/module_utils_Ansible.ModuleUtils.FileUtil/aliases
test/integration/targets/module_utils_Ansible.ModuleUtils.FileUtil/library/file_util_test.ps1
test/integration/targets/module_utils_Ansible.ModuleUtils.FileUtil/tasks/main.yml
test/integration/targets/module_utils_Ansible.ModuleUtils.Legacy/aliases
test/integration/targets/module_utils_Ansible.ModuleUtils.Legacy/library/testlist.ps1
test/integration/targets/module_utils_Ansible.ModuleUtils.Legacy/library/testpath.ps1
test/integration/targets/module_utils_Ansible.ModuleUtils.Legacy/tasks/main.yml
test/integration/targets/module_utils_Ansible.ModuleUtils.LinkUtil/aliases
test/integration/targets/module_utils_Ansible.ModuleUtils.LinkUtil/library/symbolic_link_test.ps1
test/integration/targets/module_utils_Ansible.ModuleUtils.LinkUtil/tasks/main.yml
test/integration/targets/module_utils_Ansible.ModuleUtils.PrivilegeUtil/aliases
test/integration/targets/module_utils_Ansible.ModuleUtils.PrivilegeUtil/library/privilege_util_test.ps1
test/integration/targets/module_utils_Ansible.ModuleUtils.PrivilegeUtil/tasks/main.yml
test/integration/targets/module_utils_Ansible.ModuleUtils.SID/aliases
test/integration/targets/module_utils_Ansible.ModuleUtils.SID/library/sid_utils_test.ps1
test/integration/targets/module_utils_Ansible.ModuleUtils.SID/tasks/main.yml
test/integration/targets/module_utils_Ansible.ModuleUtils.WebRequest/aliases
test/integration/targets/module_utils_Ansible.ModuleUtils.WebRequest/library/web_request_test.ps1
test/integration/targets/module_utils_Ansible.ModuleUtils.WebRequest/meta/main.yml
test/integration/targets/module_utils_Ansible.ModuleUtils.WebRequest/tasks/main.yml
test/integration/targets/module_utils_Ansible.Privilege/aliases
test/integration/targets/module_utils_Ansible.Privilege/library/ansible_privilege_tests.ps1
test/integration/targets/module_utils_Ansible.Privilege/tasks/main.yml
test/integration/targets/module_utils_Ansible.Process/aliases
test/integration/targets/module_utils_Ansible.Process/library/ansible_process_tests.ps1
test/integration/targets/module_utils_Ansible.Process/tasks/main.yml
test/integration/targets/module_utils_Ansible.Service/aliases
test/integration/targets/module_utils_Ansible.Service/library/ansible_service_tests.ps1
test/integration/targets/module_utils_Ansible.Service/tasks/main.yml
test/integration/targets/module_utils_ansible_release/aliases
test/integration/targets/module_utils_ansible_release/library/ansible_release.py
test/integration/targets/module_utils_ansible_release/tasks/main.yml
test/integration/targets/module_utils_common.respawn/aliases
test/integration/targets/module_utils_common.respawn/library/respawnme.py
test/integration/targets/module_utils_common.respawn/tasks/main.yml
test/integration/targets/module_utils_distro/aliases
test/integration/targets/module_utils_distro/runme.sh
test/integration/targets/module_utils_distro/meta/main.yml
test/integration/targets/module_utils_facts.system.selinux/aliases
test/integration/targets/module_utils_facts.system.selinux/tasks/main.yml
test/integration/targets/module_utils_facts.system.selinux/tasks/selinux.yml
test/integration/targets/module_utils_urls/aliases
test/integration/targets/module_utils_urls/library/test_peercert.py
test/integration/targets/module_utils_urls/meta/main.yml
test/integration/targets/module_utils_urls/tasks/main.yml
test/integration/targets/mount_facts/aliases
test/integration/targets/mount_facts/meta/main.yml
test/integration/targets/mount_facts/tasks/main.yml
test/integration/targets/no_log/aliases
test/integration/targets/no_log/ansible_no_log_in_result.yml
test/integration/targets/no_log/dynamic.yml
test/integration/targets/no_log/no_log_config.yml
test/integration/targets/no_log/no_log_local.yml
test/integration/targets/no_log/no_log_suboptions.yml
test/integration/targets/no_log/no_log_suboptions_invalid.yml
test/integration/targets/no_log/runme.sh
test/integration/targets/no_log/secretvars.yml
test/integration/targets/no_log/action_plugins/action_sets_no_log.py
test/integration/targets/no_log/library/module.py
test/integration/targets/noexec/aliases
test/integration/targets/noexec/inventory
test/integration/targets/noexec/runme.sh
test/integration/targets/noexec/test-noexec.yml
test/integration/targets/old_style_modules_posix/aliases
test/integration/targets/old_style_modules_posix/library/helloworld.sh
test/integration/targets/old_style_modules_posix/meta/main.yml
test/integration/targets/old_style_modules_posix/tasks/main.yml
test/integration/targets/old_style_vars_plugins/aliases
test/integration/targets/old_style_vars_plugins/runme.sh
test/integration/targets/old_style_vars_plugins/deprecation_warning/v2_vars_plugin.py
test/integration/targets/old_style_vars_plugins/roles/a/tasks/main.yml
test/integration/targets/old_style_vars_plugins/roles/a/vars_plugins/auto_role_vars.py
test/integration/targets/old_style_vars_plugins/vars_plugins/auto_enabled.py
test/integration/targets/old_style_vars_plugins/vars_plugins/implicitly_auto_enabled.py
test/integration/targets/old_style_vars_plugins/vars_plugins/require_enabled.py
test/integration/targets/omit/48673.yml
test/integration/targets/omit/75692.yml
test/integration/targets/omit/C75692.yml
test/integration/targets/omit/aliases
test/integration/targets/omit/runme.sh
test/integration/targets/order/aliases
test/integration/targets/order/inventory
test/integration/targets/order/order.yml
test/integration/targets/order/runme.sh
test/integration/targets/package/aliases
test/integration/targets/package/meta/main.yml
test/integration/targets/package/tasks/main.yml
test/integration/targets/package_facts/aliases
test/integration/targets/package_facts/runme.sh
test/integration/targets/package_facts/runme.yml
test/integration/targets/package_facts/test_warning_failed.yml
test/integration/targets/package_facts/test_warning_unusable.yml
test/integration/targets/package_facts/files/apk
test/integration/targets/package_facts/tasks/main.yml
test/integration/targets/packaging_cli-doc/aliases
test/integration/targets/packaging_cli-doc/runme.sh
test/integration/targets/packaging_cli-doc/template.j2
test/integration/targets/packaging_cli-doc/verify.py
test/integration/targets/parsing/aliases
test/integration/targets/parsing/good_parsing.yml
test/integration/targets/parsing/parsing.yml
test/integration/targets/parsing/runme.sh
test/integration/targets/parsing/roles/test_good_parsing/tasks/main.yml
test/integration/targets/parsing/roles/test_good_parsing/tasks/test_include.yml
test/integration/targets/parsing/roles/test_good_parsing/tasks/test_include_conditional.yml
test/integration/targets/parsing/roles/test_good_parsing/tasks/test_include_nested.yml
test/integration/targets/parsing/roles/test_good_parsing/vars/main.yml
test/integration/targets/path_lookups/aliases
test/integration/targets/path_lookups/play.yml
test/integration/targets/path_lookups/runme.sh
test/integration/targets/path_lookups/testplay.yml
test/integration/targets/path_lookups/roles/showfile/tasks/notmain.yml
test/integration/targets/path_with_comma_in_inventory/aliases
test/integration/targets/path_with_comma_in_inventory/playbook.yml
test/integration/targets/path_with_comma_in_inventory/runme.sh
test/integration/targets/path_with_comma_in_inventory/this,path,has,commas/hosts
test/integration/targets/path_with_comma_in_inventory/this,path,has,commas/group_vars/all.yml
test/integration/targets/pause/aliases
test/integration/targets/pause/pause-1.yml
test/integration/targets/pause/pause-2.yml
test/integration/targets/pause/pause-3.yml
test/integration/targets/pause/pause-4.yml
test/integration/targets/pause/pause-5.yml
test/integration/targets/pause/pause-6.yml
test/integration/targets/pause/runme.sh
test/integration/targets/pause/test-pause-background.yml
test/integration/targets/pause/test-pause-no-tty.yml
test/integration/targets/pause/test-pause.py
test/integration/targets/pause/test-pause.yml
test/integration/targets/ping/aliases
test/integration/targets/ping/tasks/main.yml
test/integration/targets/pip/aliases
test/integration/targets/pip/files/setup.py
test/integration/targets/pip/files/ansible_test_pip_chdir/__init__.py
test/integration/targets/pip/files/sample-project/pyproject.toml
test/integration/targets/pip/files/sample-project/src/sample_project/__init__.py
test/integration/targets/pip/meta/main.yml
test/integration/targets/pip/tasks/break_system_packages.yml
test/integration/targets/pip/tasks/default_cleanup.yml
test/integration/targets/pip/tasks/freebsd_cleanup.yml
test/integration/targets/pip/tasks/main.yml
test/integration/targets/pip/tasks/no_setuptools.yml
test/integration/targets/pip/tasks/pip.yml
test/integration/targets/pip/vars/main.yml
test/integration/targets/pkg_resources/aliases
test/integration/targets/pkg_resources/lookup_plugins/check_pkg_resources.py
test/integration/targets/pkg_resources/tasks/main.yml
test/integration/targets/play_iterator/aliases
test/integration/targets/play_iterator/playbook.yml
test/integration/targets/play_iterator/runme.sh
test/integration/targets/playbook/aliases
test/integration/targets/playbook/empty.yml
test/integration/targets/playbook/empty_hosts.yml
test/integration/targets/playbook/malformed_post_tasks.yml
test/integration/targets/playbook/malformed_pre_tasks.yml
test/integration/targets/playbook/malformed_roles.yml
test/integration/targets/playbook/malformed_tasks.yml
test/integration/targets/playbook/malformed_vars_prompt.yml
test/integration/targets/playbook/old_style_role.yml
test/integration/targets/playbook/remote_user_and_user.yml
test/integration/targets/playbook/roles_null.yml
test/integration/targets/playbook/runme.sh
test/integration/targets/playbook/some_vars.yml
test/integration/targets/playbook/timeout.yml
test/integration/targets/playbook/types.yml
test/integration/targets/playbook/user.yml
test/integration/targets/playbook/vars_files_null.yml
test/integration/targets/playbook/vars_files_string.yml
test/integration/targets/playbook/vars_prompt_null.yml
test/integration/targets/playbook_output_validator/aliases
test/integration/targets/playbook_output_validator/filter.py
test/integration/targets/plugin_config_for_inventory/aliases
test/integration/targets/plugin_config_for_inventory/config_with_parameter.yml
test/integration/targets/plugin_config_for_inventory/config_without_parameter.yml
test/integration/targets/plugin_config_for_inventory/test_inventory.py
test/integration/targets/plugin_config_for_inventory/cache_plugins/none.py
test/integration/targets/plugin_config_for_inventory/tasks/main.yml
test/integration/targets/plugin_filtering/aliases
test/integration/targets/plugin_filtering/copy.yml
test/integration/targets/plugin_filtering/filter_lookup.ini
test/integration/targets/plugin_filtering/filter_lookup.yml
test/integration/targets/plugin_filtering/filter_modules.ini
test/integration/targets/plugin_filtering/filter_modules.yml
test/integration/targets/plugin_filtering/filter_ping.ini
test/integration/targets/plugin_filtering/filter_ping.yml
test/integration/targets/plugin_filtering/filter_stat.ini
test/integration/targets/plugin_filtering/filter_stat.yml
test/integration/targets/plugin_filtering/lookup.yml
test/integration/targets/plugin_filtering/no_filters.ini
test/integration/targets/plugin_filtering/no_rejectlist_module.yml
test/integration/targets/plugin_filtering/pause.yml
test/integration/targets/plugin_filtering/ping.yml
test/integration/targets/plugin_filtering/runme.sh
test/integration/targets/plugin_filtering/stat.yml
test/integration/targets/plugin_filtering/tempfile.yml
test/integration/targets/plugin_loader/aliases
test/integration/targets/plugin_loader/runme.sh
test/integration/targets/plugin_loader/use_coll_name.yml
test/integration/targets/plugin_loader/file_collision/play.yml
test/integration/targets/plugin_loader/file_collision/roles/r1/filter_plugins/custom.py
test/integration/targets/plugin_loader/file_collision/roles/r1/filter_plugins/filter1.yml
test/integration/targets/plugin_loader/file_collision/roles/r1/filter_plugins/filter3.yml
test/integration/targets/plugin_loader/file_collision/roles/r2/filter_plugins/custom.py
test/integration/targets/plugin_loader/file_collision/roles/r2/filter_plugins/filter2.yml
test/integration/targets/plugin_loader/normal/filters.yml
test/integration/targets/plugin_loader/normal/self_referential.yml
test/integration/targets/plugin_loader/normal/underscore.yml
test/integration/targets/plugin_loader/normal/action_plugins/self_referential.py
test/integration/targets/plugin_loader/normal/library/_underscore.py
test/integration/targets/plugin_loader/override/filters.yml
test/integration/targets/plugin_loader/override/filter_plugins/core.py
test/integration/targets/plugin_namespace/aliases
test/integration/targets/plugin_namespace/filter_plugins/test_filter.py
test/integration/targets/plugin_namespace/lookup_plugins/lookup_name.py
test/integration/targets/plugin_namespace/tasks/main.yml
test/integration/targets/plugin_namespace/test_plugins/test_test.py
test/integration/targets/preflight_encoding/aliases
test/integration/targets/preflight_encoding/tasks/main.yml
test/integration/targets/preflight_encoding/vars/main.yml
test/integration/targets/prepare_http_tests/defaults/main.yml
test/integration/targets/prepare_http_tests/files/openssl_legacy.cnf
test/integration/targets/prepare_http_tests/handlers/main.yml
test/integration/targets/prepare_http_tests/library/httptester_kinit.py
test/integration/targets/prepare_http_tests/meta/main.yml
test/integration/targets/prepare_http_tests/tasks/default.yml
test/integration/targets/prepare_http_tests/tasks/kerberos.yml
test/integration/targets/prepare_http_tests/tasks/main.yml
test/integration/targets/prepare_http_tests/tasks/windows.yml
test/integration/targets/prepare_http_tests/templates/krb5.conf.j2
test/integration/targets/prepare_http_tests/vars/Alpine.yml
test/integration/targets/prepare_http_tests/vars/Debian.yml
test/integration/targets/prepare_http_tests/vars/FreeBSD.yml
test/integration/targets/prepare_http_tests/vars/RedHat-9.yml
test/integration/targets/prepare_http_tests/vars/Suse.yml
test/integration/targets/prepare_http_tests/vars/default.yml
test/integration/targets/prepare_http_tests/vars/httptester.yml
test/integration/targets/prepare_tests/tasks/main.yml
test/integration/targets/protomatter/aliases
test/integration/targets/protomatter/action_plugins/transform_factory.py
test/integration/targets/protomatter/lookup_plugins/emit_deprecation_warning.py
test/integration/targets/protomatter/lookup_plugins/synthetic_plugin_info.py
test/integration/targets/protomatter/tasks/main.yml
test/integration/targets/python_module_rlimit_nofile/aliases
test/integration/targets/python_module_rlimit_nofile/tasks/main.yml
test/integration/targets/pyyaml/aliases
test/integration/targets/pyyaml/runme.sh
test/integration/targets/raw/aliases
test/integration/targets/raw/runme.sh
test/integration/targets/raw/runme.yml
test/integration/targets/raw/meta/main.yml
test/integration/targets/raw/tasks/main.yml
test/integration/targets/reboot/aliases
test/integration/targets/reboot/handlers/main.yml
test/integration/targets/reboot/tasks/check_reboot.yml
test/integration/targets/reboot/tasks/get_boot_time.yml
test/integration/targets/reboot/tasks/main.yml
test/integration/targets/reboot/tasks/test_invalid_parameter.yml
test/integration/targets/reboot/tasks/test_invalid_test_command.yml
test/integration/targets/reboot/tasks/test_molly_guard.yml
test/integration/targets/reboot/tasks/test_standard_scenarios.yml
test/integration/targets/reboot/vars/main.yml
test/integration/targets/register/aliases
test/integration/targets/register/can_register.yml
test/integration/targets/register/invalid.yml
test/integration/targets/register/invalid_skipped.yml
test/integration/targets/register/runme.sh
test/integration/targets/rel_plugin_loading/aliases
test/integration/targets/rel_plugin_loading/notyaml.yml
test/integration/targets/rel_plugin_loading/runme.sh
test/integration/targets/rel_plugin_loading/subdir/play.yml
test/integration/targets/rel_plugin_loading/subdir/inventory_plugins/notyaml.py
test/integration/targets/remote_tmp/aliases
test/integration/targets/remote_tmp/playbook.yml
test/integration/targets/remote_tmp/runme.sh
test/integration/targets/replace/aliases
test/integration/targets/replace/meta/main.yml
test/integration/targets/replace/tasks/main.yml
test/integration/targets/result_pickle_error/aliases
test/integration/targets/result_pickle_error/runme.sh
test/integration/targets/result_pickle_error/runme.yml
test/integration/targets/result_pickle_error/action_plugins/result_pickle_error.py
test/integration/targets/result_pickle_error/tasks/main.yml
test/integration/targets/roles/47023.yml
test/integration/targets/roles/75240.yml
test/integration/targets/roles/aliases
test/integration/targets/roles/allowed_dupes.yml
test/integration/targets/roles/data_integrity.yml
test/integration/targets/roles/dupe_inheritance.yml
test/integration/targets/roles/end_role.yml
test/integration/targets/roles/end_role_handler_error.yml
test/integration/targets/roles/end_role_nested.yml
test/integration/targets/roles/no_dupes.yml
test/integration/targets/roles/no_outside.yml
test/integration/targets/roles/no_outside_import.yml
test/integration/targets/roles/privacy.yml
test/integration/targets/roles/role_complete.yml
test/integration/targets/roles/role_dep_chain.yml
test/integration/targets/roles/runme.sh
test/integration/targets/roles/test_subdirs.yml
test/integration/targets/roles/vars_scope.yml
test/integration/targets/roles/roles/47023_role1/defaults/main.yml
test/integration/targets/roles/roles/47023_role1/tasks/main.yml
test/integration/targets/roles/roles/47023_role1/vars/main.yml
test/integration/targets/roles/roles/47023_role2/tasks/main.yml
test/integration/targets/roles/roles/47023_role3/tasks/main.yml
test/integration/targets/roles/roles/47023_role4/tasks/main.yml
test/integration/targets/roles/roles/a/tasks/main.yml
test/integration/targets/roles/roles/a/tasks/subdir/entrypoint.yml
test/integration/targets/roles/roles/a/vars/main.yml
test/integration/targets/roles/roles/b/meta/main.yml
test/integration/targets/roles/roles/b/tasks/main.yml
test/integration/targets/roles/roles/bottom/tasks/main.yml
test/integration/targets/roles/roles/c/meta/main.yml
test/integration/targets/roles/roles/c/tasks/main.yml
test/integration/targets/roles/roles/data/defaults/main/00.yml
test/integration/targets/roles/roles/data/defaults/main/01.yml
test/integration/targets/roles/roles/data/tasks/main.yml
test/integration/targets/roles/roles/end_role_inside/handlers/main.yml
test/integration/targets/roles/roles/end_role_inside/tasks/main.yml
test/integration/targets/roles/roles/end_role_inside/tasks/nested.yml
test/integration/targets/roles/roles/end_role_inside_nested/tasks/import_tasks.yml
test/integration/targets/roles/roles/end_role_inside_nested/tasks/include_tasks.yml
test/integration/targets/roles/roles/end_role_inside_nested/tasks/main.yml
test/integration/targets/roles/roles/error_handler/tasks/main.yml
test/integration/targets/roles/roles/failed_when/tasks/main.yml
test/integration/targets/roles/roles/imported_from_include/tasks/main.yml
test/integration/targets/roles/roles/include_import_dep_chain/defaults/main.yml
test/integration/targets/roles/roles/include_import_dep_chain/tasks/main.yml
test/integration/targets/roles/roles/include_import_dep_chain/vars/main.yml
test/integration/targets/roles/roles/middle/tasks/main.yml
test/integration/targets/roles/roles/recover/tasks/main.yml
test/integration/targets/roles/roles/set_var/tasks/main.yml
test/integration/targets/roles/roles/test_connectivity/tasks/main.yml
test/integration/targets/roles/roles/top/tasks/main.yml
test/integration/targets/roles/roles/vars_scope/defaults/main.yml
test/integration/targets/roles/roles/vars_scope/tasks/check_vars.yml
test/integration/targets/roles/roles/vars_scope/tasks/main.yml
test/integration/targets/roles/roles/vars_scope/vars/main.yml
test/integration/targets/roles/tasks/check_vars.yml
test/integration/targets/roles/tasks/dummy.yml
test/integration/targets/roles/vars/play.yml
test/integration/targets/roles/vars/privacy_vars.yml
test/integration/targets/roles_arg_spec/aliases
test/integration/targets/roles_arg_spec/runme.sh
test/integration/targets/roles_arg_spec/test.yml
test/integration/targets/roles_arg_spec/test_complex_role_fails.yml
test/integration/targets/roles_arg_spec/test_play_level_role_fails.yml
test/integration/targets/roles_arg_spec/test_tags.yml
test/integration/targets/roles_arg_spec/collections/ansible_collections/foo/bar/MANIFEST.json
test/integration/targets/roles_arg_spec/collections/ansible_collections/foo/bar/roles/blah/meta/argument_specs.yml
test/integration/targets/roles_arg_spec/collections/ansible_collections/foo/bar/roles/blah/tasks/main.yml
test/integration/targets/roles_arg_spec/roles/a/meta/argument_specs.yml
test/integration/targets/roles_arg_spec/roles/a/meta/main.yml
test/integration/targets/roles_arg_spec/roles/a/tasks/alternate.yml
test/integration/targets/roles_arg_spec/roles/a/tasks/main.yml
test/integration/targets/roles_arg_spec/roles/a/tasks/no_spec_entrypoint.yml
test/integration/targets/roles_arg_spec/roles/b/meta/argument_specs.yaml
test/integration/targets/roles_arg_spec/roles/b/tasks/main.yml
test/integration/targets/roles_arg_spec/roles/c/meta/main.yml
test/integration/targets/roles_arg_spec/roles/c/tasks/main.yml
test/integration/targets/roles_arg_spec/roles/empty_argspec/meta/argument_specs.yml
test/integration/targets/roles_arg_spec/roles/empty_argspec/tasks/main.yml
test/integration/targets/roles_arg_spec/roles/empty_file/meta/argument_specs.yml
test/integration/targets/roles_arg_spec/roles/empty_file/tasks/main.yml
test/integration/targets/roles_arg_spec/roles/role_with_no_tasks/meta/argument_specs.yml
test/integration/targets/roles_arg_spec/roles/test1/defaults/main.yml
test/integration/targets/roles_arg_spec/roles/test1/meta/argument_specs.yml
test/integration/targets/roles_arg_spec/roles/test1/tasks/main.yml
test/integration/targets/roles_arg_spec/roles/test1/tasks/other.yml
test/integration/targets/roles_arg_spec/roles/test1/tasks/test1_other.yml
test/integration/targets/roles_arg_spec/roles/test1/vars/main.yml
test/integration/targets/roles_arg_spec/roles/test1/vars/other.yml
test/integration/targets/roles_var_inheritance/aliases
test/integration/targets/roles_var_inheritance/play.yml
test/integration/targets/roles_var_inheritance/runme.sh
test/integration/targets/roles_var_inheritance/roles/A/meta/main.yml
test/integration/targets/roles_var_inheritance/roles/B/meta/main.yml
test/integration/targets/roles_var_inheritance/roles/child_nested_dep/vars/main.yml
test/integration/targets/roles_var_inheritance/roles/common_dep/meta/main.yml
test/integration/targets/roles_var_inheritance/roles/common_dep/vars/main.yml
test/integration/targets/roles_var_inheritance/roles/nested_dep/meta/main.yml
test/integration/targets/roles_var_inheritance/roles/nested_dep/tasks/main.yml
test/integration/targets/rpm_key/aliases
test/integration/targets/rpm_key/defaults/main.yaml
test/integration/targets/rpm_key/meta/main.yml
test/integration/targets/rpm_key/tasks/main.yaml
test/integration/targets/rpm_key/tasks/rpm_key.yaml
test/integration/targets/run_modules/aliases
test/integration/targets/run_modules/args.json
test/integration/targets/run_modules/run_raw_args.yml
test/integration/targets/run_modules/runme.sh
test/integration/targets/run_modules/library/test.py
test/integration/targets/script/aliases
test/integration/targets/script/files/create_afile.sh
test/integration/targets/script/files/no_shebang.py
test/integration/targets/script/files/remove_afile.sh
test/integration/targets/script/files/test.sh
test/integration/targets/script/files/test_with_args.sh
test/integration/targets/script/files/space path/test.sh
test/integration/targets/script/meta/main.yml
test/integration/targets/script/tasks/main.yml
test/integration/targets/service/aliases
test/integration/targets/service/files/ansible-broken.upstart
test/integration/targets/service/files/ansible.rc
test/integration/targets/service/files/ansible.systemd
test/integration/targets/service/files/ansible.sysv
test/integration/targets/service/files/ansible.upstart
test/integration/targets/service/files/ansible_test_service.py
test/integration/targets/service/meta/main.yml
test/integration/targets/service/tasks/main.yml
test/integration/targets/service/tasks/rc_cleanup.yml
test/integration/targets/service/tasks/rc_setup.yml
test/integration/targets/service/tasks/systemd_cleanup.yml
test/integration/targets/service/tasks/systemd_setup.yml
test/integration/targets/service/tasks/sysv_cleanup.yml
test/integration/targets/service/tasks/sysv_setup.yml
test/integration/targets/service/tasks/tests.yml
test/integration/targets/service/tasks/upstart_cleanup.yml
test/integration/targets/service/tasks/upstart_setup.yml
test/integration/targets/service/templates/main.yml
test/integration/targets/service_facts/aliases
test/integration/targets/service_facts/files/ansible.systemd
test/integration/targets/service_facts/files/ansible_test_service.py
test/integration/targets/service_facts/handlers/main.yml
test/integration/targets/service_facts/tasks/main.yml
test/integration/targets/service_facts/tasks/systemd_cleanup.yml
test/integration/targets/service_facts/tasks/systemd_setup.yml
test/integration/targets/service_facts/tasks/tests.yml
test/integration/targets/set_fact/aliases
test/integration/targets/set_fact/incremental.yml
test/integration/targets/set_fact/inventory
test/integration/targets/set_fact/nowarn_clean_facts.yml
test/integration/targets/set_fact/runme.sh
test/integration/targets/set_fact/set_fact.yml
test/integration/targets/set_fact/set_fact_ansible_vars.yml
test/integration/targets/set_fact/set_fact_auto_unsafe.yml
test/integration/targets/set_fact/set_fact_bool_conv_jinja2_native.yml
test/integration/targets/set_fact/set_fact_cached_1.yml
test/integration/targets/set_fact/set_fact_cached_2.yml
test/integration/targets/set_fact/set_fact_empty_str_key.yml
test/integration/targets/set_fact/set_fact_no_cache.yml
test/integration/targets/set_stats/aliases
test/integration/targets/set_stats/runme.sh
test/integration/targets/set_stats/test_aggregate.yml
test/integration/targets/set_stats/test_simple.yml
test/integration/targets/setup_become_user_pair/defaults/main.yml
test/integration/targets/setup_become_user_pair/tasks/main.yml
test/integration/targets/setup_cron/defaults/main.yml
test/integration/targets/setup_cron/meta/main.yml
test/integration/targets/setup_cron/tasks/main.yml
test/integration/targets/setup_cron/vars/alpine.yml
test/integration/targets/setup_cron/vars/debian.yml
test/integration/targets/setup_cron/vars/default.yml
test/integration/targets/setup_cron/vars/fedora.yml
test/integration/targets/setup_cron/vars/freebsd.yml
test/integration/targets/setup_cron/vars/redhat.yml
test/integration/targets/setup_cron/vars/suse.yml
test/integration/targets/setup_deb_repo/files/package_specs/stable/baz-1.0.0
test/integration/targets/setup_deb_repo/files/package_specs/stable/foo-1.0.0
test/integration/targets/setup_deb_repo/files/package_specs/stable/foo-1.0.1
test/integration/targets/setup_deb_repo/files/package_specs/stable/foobar-1.0.0
test/integration/targets/setup_deb_repo/files/package_specs/stable/foobar-1.0.1
test/integration/targets/setup_deb_repo/files/package_specs/testing/foo-2.0.0
test/integration/targets/setup_deb_repo/files/package_specs/testing/foo-2.0.1
test/integration/targets/setup_deb_repo/meta/main.yml
test/integration/targets/setup_deb_repo/tasks/main.yml
test/integration/targets/setup_gnutar/handlers/main.yml
test/integration/targets/setup_gnutar/tasks/main.yml
test/integration/targets/setup_nobody/handlers/main.yml
test/integration/targets/setup_nobody/tasks/main.yml
test/integration/targets/setup_paramiko/aliases
test/integration/targets/setup_paramiko/constraints.txt
test/integration/targets/setup_paramiko/install-Alpine-3-python-3.yml
test/integration/targets/setup_paramiko/install-Darwin-python-3.yml
test/integration/targets/setup_paramiko/install-FreeBSD-python-3.yml
test/integration/targets/setup_paramiko/install-RedHat-8-python-3.yml
test/integration/targets/setup_paramiko/install-RedHat-9-python-3.yml
test/integration/targets/setup_paramiko/install-fail.yml
test/integration/targets/setup_paramiko/install-python-3.yml
test/integration/targets/setup_paramiko/install.yml
test/integration/targets/setup_paramiko/inventory
test/integration/targets/setup_paramiko/setup-remote-constraints.yml
test/integration/targets/setup_paramiko/setup.sh
test/integration/targets/setup_paramiko/uninstall-Alpine-3-python-3.yml
test/integration/targets/setup_paramiko/uninstall-Darwin-python-3.yml
test/integration/targets/setup_paramiko/uninstall-FreeBSD-python-3.yml
test/integration/targets/setup_paramiko/uninstall-RedHat-8-python-3.yml
test/integration/targets/setup_paramiko/uninstall-RedHat-9-python-3.yml
test/integration/targets/setup_paramiko/uninstall-apt-python-3.yml
test/integration/targets/setup_paramiko/uninstall-dnf.yml
test/integration/targets/setup_paramiko/uninstall-dnf5.yml
test/integration/targets/setup_paramiko/uninstall-fail.yml
test/integration/targets/setup_paramiko/uninstall-yum.yml
test/integration/targets/setup_paramiko/uninstall-zypper-python-3.yml
test/integration/targets/setup_paramiko/uninstall.yml
test/integration/targets/setup_paramiko/library/detect_paramiko.py
test/integration/targets/setup_passlib/tasks/main.yml
test/integration/targets/setup_passlib_controller/runme.sh
test/integration/targets/setup_pexpect/files/constraints.txt
test/integration/targets/setup_pexpect/meta/main.yml
test/integration/targets/setup_pexpect/tasks/main.yml
test/integration/targets/setup_remote_constraints/aliases
test/integration/targets/setup_remote_constraints/meta/main.yml
test/integration/targets/setup_remote_constraints/tasks/main.yml
test/integration/targets/setup_remote_tmp_dir/defaults/main.yml
test/integration/targets/setup_remote_tmp_dir/handlers/main.yml
test/integration/targets/setup_remote_tmp_dir/tasks/default-cleanup.yml
test/integration/targets/setup_remote_tmp_dir/tasks/default.yml
test/integration/targets/setup_remote_tmp_dir/tasks/main.yml
test/integration/targets/setup_remote_tmp_dir/tasks/windows-cleanup.yml
test/integration/targets/setup_remote_tmp_dir/tasks/windows.yml
test/integration/targets/setup_rpm_repo/defaults/main.yml
test/integration/targets/setup_rpm_repo/files/comps.xml
test/integration/targets/setup_rpm_repo/handlers/main.yml
test/integration/targets/setup_rpm_repo/library/create_repo.py
test/integration/targets/setup_rpm_repo/meta/main.yml
test/integration/targets/setup_rpm_repo/tasks/main.yml
test/integration/targets/setup_test_user/defaults/main.yml
test/integration/targets/setup_test_user/handlers/main.yml
test/integration/targets/setup_test_user/tasks/default.yml
test/integration/targets/setup_test_user/tasks/macosx.yml
test/integration/targets/setup_test_user/tasks/main.yml
test/integration/targets/setup_test_user/tasks/sudo_config.yml
test/integration/targets/setup_win_printargv/files/PrintArgv.cs
test/integration/targets/setup_win_printargv/meta/main.yml
test/integration/targets/setup_win_printargv/tasks/main.yml
test/integration/targets/shell/aliases
test/integration/targets/shell/test-command-building-playbook.yml
test/integration/targets/shell/action_plugins/test_shell.py
test/integration/targets/shell/connection_plugins/test_connection_default.py
test/integration/targets/shell/connection_plugins/test_connection_override.py
test/integration/targets/shell/meta/main.yml
test/integration/targets/shell/tasks/command-building.yml
test/integration/targets/shell/tasks/main.yml
test/integration/targets/slurp/aliases
test/integration/targets/slurp/files/bar.bin
test/integration/targets/slurp/meta/main.yml
test/integration/targets/slurp/tasks/main.yml
test/integration/targets/slurp/tasks/test_unreadable.yml
test/integration/targets/special_vars/aliases
test/integration/targets/special_vars/meta/main.yml
test/integration/targets/special_vars/tasks/main.yml
test/integration/targets/special_vars/templates/foo.j2
test/integration/targets/special_vars/vars/main.yml
test/integration/targets/special_vars_hosts/aliases
test/integration/targets/special_vars_hosts/inventory
test/integration/targets/special_vars_hosts/playbook.yml
test/integration/targets/special_vars_hosts/runme.sh
test/integration/targets/split/aliases
test/integration/targets/split/tasks/main.yml
test/integration/targets/ssh_agent/aliases
test/integration/targets/ssh_agent/auto.yml
test/integration/targets/ssh_agent/test_key.yml
test/integration/targets/ssh_agent/action_plugins/ssh_agent.py
test/integration/targets/ssh_agent/action_plugins/ssh_keygen.py
test/integration/targets/ssh_agent/tasks/main.yml
test/integration/targets/ssh_agent/tasks/tests.yml
test/integration/targets/stat/aliases
test/integration/targets/stat/files/foo.txt
test/integration/targets/stat/meta/main.yml
test/integration/targets/stat/tasks/main.yml
test/integration/targets/strategy-external/aliases
test/integration/targets/strategy-external/runme.sh
test/integration/targets/strategy-external/ansible_collections/ns/col/plugins/strategy/external.py
test/integration/targets/strategy_free/aliases
test/integration/targets/strategy_free/inventory
test/integration/targets/strategy_free/last_include_tasks.yml
test/integration/targets/strategy_free/runme.sh
test/integration/targets/strategy_free/test_last_include_in_always.yml
test/integration/targets/strategy_host_pinned/aliases
test/integration/targets/strategy_host_pinned/hosts
test/integration/targets/strategy_host_pinned/playbook.yml
test/integration/targets/strategy_host_pinned/runme.sh
test/integration/targets/strategy_host_pinned/callback_plugins/callback_host_count.py
test/integration/targets/strategy_linear/aliases
test/integration/targets/strategy_linear/inventory
test/integration/targets/strategy_linear/runme.sh
test/integration/targets/strategy_linear/task_action_templating.yml
test/integration/targets/strategy_linear/task_templated_run_once.yml
test/integration/targets/strategy_linear/test_include_file_noop.yml
test/integration/targets/strategy_linear/roles/role1/tasks/main.yml
test/integration/targets/strategy_linear/roles/role1/tasks/tasks.yml
test/integration/targets/strategy_linear/roles/role2/tasks/main.yml
test/integration/targets/subversion/aliases
test/integration/targets/subversion/runme.sh
test/integration/targets/subversion/runme.yml
test/integration/targets/subversion/roles/subversion/defaults/main.yml
test/integration/targets/subversion/roles/subversion/files/create_repo.sh
test/integration/targets/subversion/roles/subversion/tasks/cleanup.yml
test/integration/targets/subversion/roles/subversion/tasks/main.yml
test/integration/targets/subversion/roles/subversion/tasks/setup.yml
test/integration/targets/subversion/roles/subversion/tasks/tests.yml
test/integration/targets/subversion/roles/subversion/tasks/warnings.yml
test/integration/targets/subversion/roles/subversion/templates/subversion.conf.j2
test/integration/targets/subversion/vars/Alpine.yml
test/integration/targets/subversion/vars/Debian.yml
test/integration/targets/subversion/vars/FreeBSD.yml
test/integration/targets/subversion/vars/RedHat.yml
test/integration/targets/support-callback_plugins/aliases
test/integration/targets/support-callback_plugins/callback_plugins/callback_debug.py
test/integration/targets/systemd/aliases
test/integration/targets/systemd/defaults/main.yml
test/integration/targets/systemd/handlers/main.yml
test/integration/targets/systemd/meta/main.yml
test/integration/targets/systemd/tasks/main.yml
test/integration/targets/systemd/tasks/test_enabled_runtime.yml
test/integration/targets/systemd/tasks/test_indirect_service.yml
test/integration/targets/systemd/tasks/test_mask.yml
test/integration/targets/systemd/tasks/test_systemd_version.yml
test/integration/targets/systemd/tasks/test_unit_template.yml
test/integration/targets/systemd/templates/baz.service
test/integration/targets/systemd/templates/dummy.service
test/integration/targets/systemd/templates/dummy.socket
test/integration/targets/systemd/templates/mask_me.service
test/integration/targets/systemd/templates/sleeper@.service
test/integration/targets/systemd/vars/Debian.yml
test/integration/targets/systemd/vars/default.yml
test/integration/targets/tags/aliases
test/integration/targets/tags/ansible_run_tags.yml
test/integration/targets/tags/runme.sh
test/integration/targets/tags/test_tags.yml
test/integration/targets/tags/test_template_parent_tags.yml
test/integration/targets/task-args/aliases
test/integration/targets/task-args/action_plugins/echo.py
test/integration/targets/task-args/action_plugins/echo_raw.py
test/integration/targets/task-args/tasks/main.yml
test/integration/targets/task_ordering/aliases
test/integration/targets/task_ordering/meta/main.yml
test/integration/targets/task_ordering/tasks/main.yml
test/integration/targets/task_ordering/tasks/taskorder-include.yml
test/integration/targets/tasks/aliases
test/integration/targets/tasks/playbook.yml
test/integration/targets/tasks/runme.sh
test/integration/targets/tasks/action_plugins/action_that_fails.py
test/integration/targets/tempfile/aliases
test/integration/targets/tempfile/meta/main.yml
test/integration/targets/tempfile/tasks/main.yml
test/integration/targets/template/6653.yml
test/integration/targets/template/72262.yml
test/integration/targets/template/72615.yml
test/integration/targets/template/aliases
test/integration/targets/template/ansible_managed.cfg
test/integration/targets/template/ansible_managed.yml
test/integration/targets/template/ansible_managed_templated.cfg
test/integration/targets/template/arg_template_overrides.j2
test/integration/targets/template/badnull1.cfg
test/integration/targets/template/badnull2.cfg
test/integration/targets/template/badnull3.cfg
test/integration/targets/template/corner_cases.yml
test/integration/targets/template/custom_template.yml
test/integration/targets/template/filter_plugins.yml
test/integration/targets/template/in_template_overrides.j2
test/integration/targets/template/lazy_eval.yml
test/integration/targets/template/runme.sh
test/integration/targets/template/template.yml
test/integration/targets/template/template_overrides.yml
test/integration/targets/template/undefined_in_import-import.j2
test/integration/targets/template/undefined_in_import.j2
test/integration/targets/template/undefined_in_import.yml
test/integration/targets/template/undefined_var_info.yml
test/integration/targets/template/unsafe.yml
test/integration/targets/template/unused_vars_include.yml
test/integration/targets/template/custom_tasks/tasks/main.yml
test/integration/targets/template/custom_tasks/templates/test
test/integration/targets/template/files/custom_comment_string.expected
test/integration/targets/template/files/encoding_1252_utf-8.expected
test/integration/targets/template/files/encoding_1252_windows-1252.expected
test/integration/targets/template/files/foo-py26.txt
test/integration/targets/template/files/foo.dos.txt
test/integration/targets/template/files/foo.txt
test/integration/targets/template/files/foo.unix.txt
test/integration/targets/template/files/import_as.expected
test/integration/targets/template/files/import_as_with_context.expected
test/integration/targets/template/files/import_with_context.expected
test/integration/targets/template/files/lstrip_blocks_false.expected
test/integration/targets/template/files/lstrip_blocks_true.expected
test/integration/targets/template/files/override_colon_value.expected
test/integration/targets/template/files/string_type_filters.expected
test/integration/targets/template/files/trim_blocks_false.expected
test/integration/targets/template/files/trim_blocks_true.expected
test/integration/targets/template/meta/main.yml
test/integration/targets/template/role_filter/filter_plugins/myplugin.py
test/integration/targets/template/role_filter/tasks/main.yml
test/integration/targets/template/tasks/backup_test.yml
test/integration/targets/template/tasks/main.yml
test/integration/targets/template/templates/%necho Onii-chan help Im stuck;exit 1%n.j2
test/integration/targets/template/templates/6653-include.j2
test/integration/targets/template/templates/6653.j2
test/integration/targets/template/templates/72262-included.j2
test/integration/targets/template/templates/72262-vars.j2
test/integration/targets/template/templates/72262.j2
test/integration/targets/template/templates/72615-macro-nested.j2
test/integration/targets/template/templates/72615-macro.j2
test/integration/targets/template/templates/72615.j2
test/integration/targets/template/templates/bar
test/integration/targets/template/templates/café.j2
test/integration/targets/template/templates/completely{{ 1 % 0 }} safe template.j2
test/integration/targets/template/templates/custom_comment_string.j2
test/integration/targets/template/templates/empty_template.j2
test/integration/targets/template/templates/encoding_1252.j2
test/integration/targets/template/templates/foo.j2
test/integration/targets/template/templates/foo2.j2
test/integration/targets/template/templates/foo3.j2
test/integration/targets/template/templates/for_loop.j2
test/integration/targets/template/templates/for_loop_include.j2
test/integration/targets/template/templates/for_loop_include_nested.j2
test/integration/targets/template/templates/import_as.j2
test/integration/targets/template/templates/import_as_with_context.j2
test/integration/targets/template/templates/import_with_context.j2
test/integration/targets/template/templates/indirect_dict.j2
test/integration/targets/template/templates/json_macro.j2
test/integration/targets/template/templates/lstrip_blocks.j2
test/integration/targets/template/templates/macro_using_globals.j2
test/integration/targets/template/templates/none.j2
test/integration/targets/template/templates/override_colon_value.j2
test/integration/targets/template/templates/override_separator.j2
test/integration/targets/template/templates/parent.j2
test/integration/targets/template/templates/qux
test/integration/targets/template/templates/short.j2
test/integration/targets/template/templates/subtemplate.j2
test/integration/targets/template/templates/template_destpath_test.j2
test/integration/targets/template/templates/template_import_macro_globals.j2
test/integration/targets/template/templates/trim_blocks.j2
test/integration/targets/template/templates/unused_vars_include.j2
test/integration/targets/template/templates/unused_vars_template.j2
test/integration/targets/template/vars/main.yml
test/integration/targets/template_jinja2_non_native/46169.yml
test/integration/targets/template_jinja2_non_native/aliases
test/integration/targets/template_jinja2_non_native/macro_override.yml
test/integration/targets/template_jinja2_non_native/runme.sh
test/integration/targets/template_jinja2_non_native/templates/46169.json.j2
test/integration/targets/template_jinja2_non_native/templates/macro_override.j2
test/integration/targets/templating/aliases
test/integration/targets/templating/filter_plugins/broken_filter.py
test/integration/targets/templating/library/noisy.py
test/integration/targets/templating/lookup_plugins/broken.py
test/integration/targets/templating/tasks/main.yml
test/integration/targets/templating/tasks/plugin_errors.yml
test/integration/targets/templating/test_plugins/broken_test.py
test/integration/targets/templating_lookup_args/aliases
test/integration/targets/templating_lookup_args/runme.sh
test/integration/targets/templating_lookup_args/test.yml
test/integration/targets/templating_lookup_args/lookup_plugins/accept_args_markers.py
test/integration/targets/templating_lookup_args/lookup_plugins/accept_no_markers.py
test/integration/targets/templating_lookups/aliases
test/integration/targets/templating_lookups/runme.sh
test/integration/targets/templating_lookups/runme.yml
test/integration/targets/templating_lookups/template_deepcopy/hosts
test/integration/targets/templating_lookups/template_deepcopy/playbook.yml
test/integration/targets/templating_lookups/template_deepcopy/template.in
test/integration/targets/templating_lookups/template_lookup_vaulted/playbook.yml
test/integration/targets/templating_lookups/template_lookup_vaulted/test_vault_pass
test/integration/targets/templating_lookups/template_lookup_vaulted/templates/vaulted_hello.j2
test/integration/targets/templating_lookups/template_lookups/tasks/errors.yml
test/integration/targets/templating_lookups/template_lookups/tasks/main.yml
test/integration/targets/templating_lookups/template_lookups/vars/main.yml
test/integration/targets/templating_settings/aliases
test/integration/targets/templating_settings/dont_warn_register.yml
test/integration/targets/templating_settings/runme.sh
test/integration/targets/templating_settings/test_templating_settings.yml
test/integration/targets/test_core/aliases
test/integration/targets/test_core/inventory
test/integration/targets/test_core/runme.sh
test/integration/targets/test_core/runme.yml
test/integration/targets/test_core/vault-password
test/integration/targets/test_core/files/notvault
test/integration/targets/test_core/files/vault1
test/integration/targets/test_core/files/vault2
test/integration/targets/test_core/tasks/main.yml
test/integration/targets/test_files/aliases
test/integration/targets/test_files/tasks/main.yml
test/integration/targets/test_mathstuff/aliases
test/integration/targets/test_mathstuff/tasks/main.yml
test/integration/targets/test_uri/aliases
test/integration/targets/test_uri/tasks/main.yml
test/integration/targets/test_utils/aliases
test/integration/targets/test_utils/scripts/timeout.py
test/integration/targets/throttle/aliases
test/integration/targets/throttle/inventory
test/integration/targets/throttle/non_integer_throttle.yml
test/integration/targets/throttle/runme.sh
test/integration/targets/throttle/test_throttle.py
test/integration/targets/throttle/test_throttle.yml
test/integration/targets/throttle/undefined_throttle.yml
test/integration/targets/throttle/group_vars/all.yml
test/integration/targets/unarchive/aliases
test/integration/targets/unarchive/runme.sh
test/integration/targets/unarchive/runme.yml
test/integration/targets/unarchive/test_relative_tmp_dir.yml
test/integration/targets/unarchive/files/content_differs.tar.gz
test/integration/targets/unarchive/files/content_differs_2.tar.gz
test/integration/targets/unarchive/files/foo.txt
test/integration/targets/unarchive/files/size_differs.tar.gz
test/integration/targets/unarchive/files/size_differs_2.tar.gz
test/integration/targets/unarchive/files/test-unarchive-nonascii-くらとみ.tar.gz
test/integration/targets/unarchive/handlers/main.yml
test/integration/targets/unarchive/meta/main.yml
test/integration/targets/unarchive/tasks/main.yml
test/integration/targets/unarchive/tasks/prepare_tests.yml
test/integration/targets/unarchive/tasks/test_different_language_var.yml
test/integration/targets/unarchive/tasks/test_download.yml
test/integration/targets/unarchive/tasks/test_exclude.yml
test/integration/targets/unarchive/tasks/test_include.yml
test/integration/targets/unarchive/tasks/test_invalid_options.yml
test/integration/targets/unarchive/tasks/test_missing_binaries.yml
test/integration/targets/unarchive/tasks/test_missing_files.yml
test/integration/targets/unarchive/tasks/test_mode.yml
test/integration/targets/unarchive/tasks/test_non_ascii_filename.yml
test/integration/targets/unarchive/tasks/test_owner_group.yml
test/integration/targets/unarchive/tasks/test_ownership_top_folder.yml
test/integration/targets/unarchive/tasks/test_parent_not_writeable.yml
test/integration/targets/unarchive/tasks/test_quotable_characters.yml
test/integration/targets/unarchive/tasks/test_relative_dest.yml
test/integration/targets/unarchive/tasks/test_symlink.yml
test/integration/targets/unarchive/tasks/test_tar.yml
test/integration/targets/unarchive/tasks/test_tar_gz.yml
test/integration/targets/unarchive/tasks/test_tar_gz_content_differs.yml
test/integration/targets/unarchive/tasks/test_tar_gz_creates.yml
test/integration/targets/unarchive/tasks/test_tar_gz_keep_newer.yml
test/integration/targets/unarchive/tasks/test_tar_gz_owner_group.yml
test/integration/targets/unarchive/tasks/test_tar_gz_size_differs.yml
test/integration/targets/unarchive/tasks/test_tar_zst.yml
test/integration/targets/unarchive/tasks/test_unprivileged_user.yml
test/integration/targets/unarchive/tasks/test_zip.yml
test/integration/targets/unarchive/vars/Darwin.yml
test/integration/targets/unarchive/vars/FreeBSD.yml
test/integration/targets/unarchive/vars/Linux.yml
test/integration/targets/undefined/aliases
test/integration/targets/undefined/tasks/main.yml
test/integration/targets/unexpected_executor_exception/aliases
test/integration/targets/unexpected_executor_exception/action_plugins/unexpected.py
test/integration/targets/unexpected_executor_exception/tasks/main.yml
test/integration/targets/unicode/aliases
test/integration/targets/unicode/inventory
test/integration/targets/unicode/runme.sh
test/integration/targets/unicode/unicode-test-script
test/integration/targets/unicode/unicode.yml
test/integration/targets/unicode/křížek-ansible-project/ansible.cfg
test/integration/targets/unsafe_writes/aliases
test/integration/targets/unsafe_writes/basic.yml
test/integration/targets/unsafe_writes/runme.sh
test/integration/targets/until/aliases
test/integration/targets/until/action_plugins/shell_no_failed.py
test/integration/targets/until/tasks/main.yml
test/integration/targets/unvault/aliases
test/integration/targets/unvault/main.yml
test/integration/targets/unvault/password
test/integration/targets/unvault/runme.sh
test/integration/targets/unvault/vault
test/integration/targets/uri/aliases
test/integration/targets/uri/files/README
test/integration/targets/uri/files/fail0.json
test/integration/targets/uri/files/fail1.json
test/integration/targets/uri/files/fail10.json
test/integration/targets/uri/files/fail11.json
test/integration/targets/uri/files/fail12.json
test/integration/targets/uri/files/fail13.json
test/integration/targets/uri/files/fail14.json
test/integration/targets/uri/files/fail15.json
test/integration/targets/uri/files/fail16.json
test/integration/targets/uri/files/fail17.json
test/integration/targets/uri/files/fail18.json
test/integration/targets/uri/files/fail19.json
test/integration/targets/uri/files/fail2.json
test/integration/targets/uri/files/fail20.json
test/integration/targets/uri/files/fail21.json
test/integration/targets/uri/files/fail22.json
test/integration/targets/uri/files/fail23.json
test/integration/targets/uri/files/fail24.json
test/integration/targets/uri/files/fail25.json
test/integration/targets/uri/files/fail26.json
test/integration/targets/uri/files/fail27.json
test/integration/targets/uri/files/fail28.json
test/integration/targets/uri/files/fail29.json
test/integration/targets/uri/files/fail3.json
test/integration/targets/uri/files/fail30.json
test/integration/targets/uri/files/fail4.json
test/integration/targets/uri/files/fail5.json
test/integration/targets/uri/files/fail6.json
test/integration/targets/uri/files/fail7.json
test/integration/targets/uri/files/fail8.json
test/integration/targets/uri/files/fail9.json
test/integration/targets/uri/files/formdata.txt
test/integration/targets/uri/files/pass0.json
test/integration/targets/uri/files/pass1.json
test/integration/targets/uri/files/pass2.json
test/integration/targets/uri/files/pass3.json
test/integration/targets/uri/files/pass4.json
test/integration/targets/uri/files/testserver.py
test/integration/targets/uri/meta/main.yml
test/integration/targets/uri/tasks/ciphers.yml
test/integration/targets/uri/tasks/install-socat-and-test-unix-socket.yml
test/integration/targets/uri/tasks/main.yml
test/integration/targets/uri/tasks/redirect-all.yml
test/integration/targets/uri/tasks/redirect-none.yml
test/integration/targets/uri/tasks/redirect-safe.yml
test/integration/targets/uri/tasks/redirect-urllib2.yml
test/integration/targets/uri/tasks/return-content.yml
test/integration/targets/uri/tasks/unexpected-failures.yml
test/integration/targets/uri/tasks/unix-socket.yml
test/integration/targets/uri/tasks/use_gssapi.yml
test/integration/targets/uri/tasks/use_netrc.yml
test/integration/targets/uri/templates/netrc.j2
test/integration/targets/user/aliases
test/integration/targets/user/files/userlist.sh
test/integration/targets/user/files/skel/.ssh/known_hosts
test/integration/targets/user/meta/main.yml
test/integration/targets/user/tasks/main.yml
test/integration/targets/user/tasks/ssh_keygen.yml
test/integration/targets/user/tasks/test_create_system_user.yml
test/integration/targets/user/tasks/test_create_user.yml
test/integration/targets/user/tasks/test_create_user_home.yml
test/integration/targets/user/tasks/test_create_user_min_max.yml
test/integration/targets/user/tasks/test_create_user_password.yml
test/integration/targets/user/tasks/test_create_user_uid.yml
test/integration/targets/user/tasks/test_expires.yml
test/integration/targets/user/tasks/test_expires_min_max.yml
test/integration/targets/user/tasks/test_expires_new_account.yml
test/integration/targets/user/tasks/test_expires_new_account_epoch_negative.yml
test/integration/targets/user/tasks/test_expires_no_shadow.yml
test/integration/targets/user/tasks/test_expires_warn.yml
test/integration/targets/user/tasks/test_inactive_new_account.yml
test/integration/targets/user/tasks/test_local.yml
test/integration/targets/user/tasks/test_local_expires.yml
test/integration/targets/user/tasks/test_no_home_fallback.yml
test/integration/targets/user/tasks/test_password_lock.yml
test/integration/targets/user/tasks/test_password_lock_new_user.yml
test/integration/targets/user/tasks/test_remove_user.yml
test/integration/targets/user/tasks/test_shadow_backup.yml
test/integration/targets/user/tasks/test_ssh_key_passphrase.yml
test/integration/targets/user/tasks/test_umask.yml
test/integration/targets/user/vars/main.yml
test/integration/targets/var_blending/aliases
test/integration/targets/var_blending/inventory
test/integration/targets/var_blending/runme.sh
test/integration/targets/var_blending/test_var_blending.yml
test/integration/targets/var_blending/test_vars.yml
test/integration/targets/var_blending/vars_file.yml
test/integration/targets/var_blending/group_vars/all
test/integration/targets/var_blending/group_vars/local
test/integration/targets/var_blending/host_vars/testhost
test/integration/targets/var_blending/roles/test_var_blending/defaults/main.yml
test/integration/targets/var_blending/roles/test_var_blending/files/foo.txt
test/integration/targets/var_blending/roles/test_var_blending/tasks/main.yml
test/integration/targets/var_blending/roles/test_var_blending/templates/foo.j2
test/integration/targets/var_blending/roles/test_var_blending/vars/main.yml
test/integration/targets/var_blending/roles/test_var_blending/vars/more_vars.yml
test/integration/targets/var_inheritance/aliases
test/integration/targets/var_inheritance/tasks/main.yml
test/integration/targets/var_precedence/aliases
test/integration/targets/var_precedence/ansible-var-precedence-check.py
test/integration/targets/var_precedence/inventory
test/integration/targets/var_precedence/runme.sh
test/integration/targets/var_precedence/test_var_precedence.yml
test/integration/targets/var_precedence/host_vars/testhost
test/integration/targets/var_precedence/roles/test_var_precedence/meta/main.yml
test/integration/targets/var_precedence/roles/test_var_precedence/tasks/main.yml
test/integration/targets/var_precedence/roles/test_var_precedence_dep/defaults/main.yml
test/integration/targets/var_precedence/roles/test_var_precedence_dep/tasks/main.yml
test/integration/targets/var_precedence/roles/test_var_precedence_dep/vars/main.yml
test/integration/targets/var_precedence/roles/test_var_precedence_inven_override/tasks/main.yml
test/integration/targets/var_precedence/roles/test_var_precedence_role1/defaults/main.yml
test/integration/targets/var_precedence/roles/test_var_precedence_role1/meta/main.yml
test/integration/targets/var_precedence/roles/test_var_precedence_role1/tasks/main.yml
test/integration/targets/var_precedence/roles/test_var_precedence_role1/vars/main.yml
test/integration/targets/var_precedence/roles/test_var_precedence_role2/defaults/main.yml
test/integration/targets/var_precedence/roles/test_var_precedence_role2/tasks/main.yml
test/integration/targets/var_precedence/roles/test_var_precedence_role2/vars/main.yml
test/integration/targets/var_precedence/roles/test_var_precedence_role3/defaults/main.yml
test/integration/targets/var_precedence/roles/test_var_precedence_role3/tasks/main.yml
test/integration/targets/var_precedence/roles/test_var_precedence_role3/vars/main.yml
test/integration/targets/var_precedence/vars/test_var_precedence.yml
test/integration/targets/var_reserved/aliases
test/integration/targets/var_reserved/tasks/block_vars.yml
test/integration/targets/var_reserved/tasks/include_vars.yml
test/integration/targets/var_reserved/tasks/main.yml
test/integration/targets/var_reserved/tasks/play_vars.yml
test/integration/targets/var_reserved/tasks/set_fact.yml
test/integration/targets/var_reserved/tasks/task_vars.yml
test/integration/targets/var_reserved/tasks/task_vars_used.yml
test/integration/targets/var_reserved/vars/set_host_variable.yml
test/integration/targets/var_templating/aliases
test/integration/targets/var_templating/ansible_debug_template.j2
test/integration/targets/var_templating/runme.sh
test/integration/targets/var_templating/task_vars_templating.yml
test/integration/targets/var_templating/test_connection_vars.yml
test/integration/targets/var_templating/undall.yml
test/integration/targets/var_templating/undefined.yml
test/integration/targets/var_templating/group_vars/all.yml
test/integration/targets/var_templating/vars/connection.yml
test/integration/targets/vars_files/aliases
test/integration/targets/vars_files/inventory
test/integration/targets/vars_files/runme.sh
test/integration/targets/vars_files/runme.yml
test/integration/targets/vars_files/validate.yml
test/integration/targets/vars_files/vars/bar.yml
test/integration/targets/vars_files/vars/common.yml
test/integration/targets/vars_files/vars/defaults.yml
test/integration/targets/wait_for/aliases
test/integration/targets/wait_for/files/testserver.py
test/integration/targets/wait_for/files/write_utf16.py
test/integration/targets/wait_for/files/zombie.py
test/integration/targets/wait_for/meta/main.yml
test/integration/targets/wait_for/tasks/main.yml
test/integration/targets/wait_for/vars/main.yml
test/integration/targets/wait_for_connection/aliases
test/integration/targets/wait_for_connection/tasks/main.yml
test/integration/targets/want_json_modules_posix/aliases
test/integration/targets/want_json_modules_posix/library/helloworld.py
test/integration/targets/want_json_modules_posix/meta/main.yml
test/integration/targets/want_json_modules_posix/tasks/main.yml
test/integration/targets/win_async_wrapper/aliases
test/integration/targets/win_async_wrapper/library/async_test.ps1
test/integration/targets/win_async_wrapper/tasks/main.yml
test/integration/targets/win_become/aliases
test/integration/targets/win_become/tasks/main.yml
test/integration/targets/win_exec_wrapper/aliases
test/integration/targets/win_exec_wrapper/action_plugins/test_rc_1.py
test/integration/targets/win_exec_wrapper/library/test_all_options.ps1
test/integration/targets/win_exec_wrapper/library/test_exec_wrapper_scope.ps1
test/integration/targets/win_exec_wrapper/library/test_fail.ps1
test/integration/targets/win_exec_wrapper/library/test_invalid_requires.ps1
test/integration/targets/win_exec_wrapper/library/test_min_os_version.ps1
test/integration/targets/win_exec_wrapper/library/test_min_ps_version.ps1
test/integration/targets/win_exec_wrapper/library/test_rc_1.ps1
test/integration/targets/win_exec_wrapper/module_utils/Ansible.ModuleUtils.ScopedUtil.psm1
test/integration/targets/win_exec_wrapper/tasks/main.yml
test/integration/targets/win_fetch/aliases
test/integration/targets/win_fetch/meta/main.yml
test/integration/targets/win_fetch/tasks/main.yml
test/integration/targets/win_module_utils/aliases
test/integration/targets/win_module_utils/library/csharp_util.ps1
test/integration/targets/win_module_utils/library/legacy_only_new_way.ps1
test/integration/targets/win_module_utils/library/legacy_only_new_way_win_line_ending.ps1
test/integration/targets/win_module_utils/library/legacy_only_old_way.ps1
test/integration/targets/win_module_utils/library/legacy_only_old_way_win_line_ending.ps1
test/integration/targets/win_module_utils/library/recursive_requires.ps1
test/integration/targets/win_module_utils/library/uses_bogus_utils.ps1
test/integration/targets/win_module_utils/library/uses_local_utils.ps1
test/integration/targets/win_module_utils/module_utils/Ansible.ModuleUtils.Recursive1.psm1
test/integration/targets/win_module_utils/module_utils/Ansible.ModuleUtils.Recursive2.psm1
test/integration/targets/win_module_utils/module_utils/Ansible.ModuleUtils.Recursive3.psm1
test/integration/targets/win_module_utils/module_utils/Ansible.ModuleUtils.ValidTestModule.psm1
test/integration/targets/win_module_utils/module_utils/Ansible.Test.cs
test/integration/targets/win_module_utils/tasks/main.yml
test/integration/targets/win_raw/aliases
test/integration/targets/win_raw/tasks/main.yml
test/integration/targets/win_script/aliases
test/integration/targets/win_script/defaults/main.yml
test/integration/targets/win_script/files/fail.bat
test/integration/targets/win_script/files/test_script.bat
test/integration/targets/win_script/files/test_script.cmd
test/integration/targets/win_script/files/test_script.ps1
test/integration/targets/win_script/files/test_script_bool.ps1
test/integration/targets/win_script/files/test_script_creates_file.ps1
test/integration/targets/win_script/files/test_script_removes_file.ps1
test/integration/targets/win_script/files/test_script_whoami.ps1
test/integration/targets/win_script/files/test_script_with_args.ps1
test/integration/targets/win_script/files/test_script_with_env.ps1
test/integration/targets/win_script/files/test_script_with_errors.ps1
test/integration/targets/win_script/files/test_script_with_native_stderr.ps1
test/integration/targets/win_script/files/test_script_with_splatting.ps1
test/integration/targets/win_script/files/space path/test_script.ps1
test/integration/targets/win_script/tasks/main.yml
test/integration/targets/windows-minimal/aliases
test/integration/targets/windows-minimal/library/test_no_exec_wrapper.ps1
test/integration/targets/windows-minimal/library/win_ping.ps1
test/integration/targets/windows-minimal/library/win_ping.py
test/integration/targets/windows-minimal/library/win_ping_set_attr.ps1
test/integration/targets/windows-minimal/library/win_ping_strict_mode_error.ps1
test/integration/targets/windows-minimal/library/win_ping_syntax_error.ps1
test/integration/targets/windows-minimal/library/win_ping_throw.ps1
test/integration/targets/windows-minimal/library/win_ping_throw_string.ps1
test/integration/targets/windows-minimal/meta/main.yml
test/integration/targets/windows-minimal/tasks/main.yml
test/integration/targets/windows-paths/aliases
test/integration/targets/windows-paths/tasks/main.yml
test/integration/targets/yaml_parsing/aliases
test/integration/targets/yaml_parsing/playbook.yml
test/integration/targets/yaml_parsing/tasks/main.yml
test/integration/targets/yaml_parsing/tasks/unsafe.yml
test/integration/targets/yaml_parsing/vars/main.yml
test/integration/targets/yum_repository/aliases
test/integration/targets/yum_repository/defaults/main.yml
test/integration/targets/yum_repository/handlers/main.yml
test/integration/targets/yum_repository/meta/main.yml
test/integration/targets/yum_repository/tasks/main.yml
test/lib/ansible_test/__init__.py
test/lib/ansible_test/_data/ansible.cfg
test/lib/ansible_test/_data/coveragerc
test/lib/ansible_test/_data/completion/docker.txt
test/lib/ansible_test/_data/completion/network.txt
test/lib/ansible_test/_data/completion/remote.txt
test/lib/ansible_test/_data/completion/windows.txt
test/lib/ansible_test/_data/playbooks/posix_coverage_setup.yml
test/lib/ansible_test/_data/playbooks/posix_coverage_teardown.yml
test/lib/ansible_test/_data/playbooks/posix_hosts_prepare.yml
test/lib/ansible_test/_data/playbooks/posix_hosts_restore.yml
test/lib/ansible_test/_data/playbooks/pypi_proxy_prepare.yml
test/lib/ansible_test/_data/playbooks/pypi_proxy_restore.yml
test/lib/ansible_test/_data/playbooks/windows_coverage_setup.yml
test/lib/ansible_test/_data/playbooks/windows_coverage_teardown.yml
test/lib/ansible_test/_data/playbooks/windows_hosts_prepare.ps1
test/lib/ansible_test/_data/playbooks/windows_hosts_prepare.yml
test/lib/ansible_test/_data/playbooks/windows_hosts_restore.ps1
test/lib/ansible_test/_data/playbooks/windows_hosts_restore.yml
test/lib/ansible_test/_data/pytest/config/default.ini
test/lib/ansible_test/_data/pytest/config/legacy.ini
test/lib/ansible_test/_data/requirements/ansible-test.txt
test/lib/ansible_test/_data/requirements/ansible.txt
test/lib/ansible_test/_data/requirements/constraints.txt
test/lib/ansible_test/_data/requirements/sanity.ansible-doc.in
test/lib/ansible_test/_data/requirements/sanity.ansible-doc.txt
test/lib/ansible_test/_data/requirements/sanity.changelog.in
test/lib/ansible_test/_data/requirements/sanity.changelog.txt
test/lib/ansible_test/_data/requirements/sanity.import.in
test/lib/ansible_test/_data/requirements/sanity.import.plugin.in
test/lib/ansible_test/_data/requirements/sanity.import.plugin.txt
test/lib/ansible_test/_data/requirements/sanity.import.txt
test/lib/ansible_test/_data/requirements/sanity.integration-aliases.in
test/lib/ansible_test/_data/requirements/sanity.integration-aliases.txt
test/lib/ansible_test/_data/requirements/sanity.pep8.in
test/lib/ansible_test/_data/requirements/sanity.pep8.txt
test/lib/ansible_test/_data/requirements/sanity.pslint.ps1
test/lib/ansible_test/_data/requirements/sanity.pylint.in
test/lib/ansible_test/_data/requirements/sanity.pylint.txt
test/lib/ansible_test/_data/requirements/sanity.runtime-metadata.in
test/lib/ansible_test/_data/requirements/sanity.runtime-metadata.txt
test/lib/ansible_test/_data/requirements/sanity.validate-modules.in
test/lib/ansible_test/_data/requirements/sanity.validate-modules.txt
test/lib/ansible_test/_data/requirements/sanity.yamllint.in
test/lib/ansible_test/_data/requirements/sanity.yamllint.txt
test/lib/ansible_test/_data/requirements/units.txt
test/lib/ansible_test/_data/requirements/windows-integration.txt
test/lib/ansible_test/_internal/__init__.py
test/lib/ansible_test/_internal/ansible_util.py
test/lib/ansible_test/_internal/become.py
test/lib/ansible_test/_internal/bootstrap.py
test/lib/ansible_test/_internal/cache.py
test/lib/ansible_test/_internal/cgroup.py
test/lib/ansible_test/_internal/completion.py
test/lib/ansible_test/_internal/config.py
test/lib/ansible_test/_internal/connections.py
test/lib/ansible_test/_internal/constants.py
test/lib/ansible_test/_internal/containers.py
test/lib/ansible_test/_internal/content_config.py
test/lib/ansible_test/_internal/core_ci.py
test/lib/ansible_test/_internal/coverage_util.py
test/lib/ansible_test/_internal/data.py
test/lib/ansible_test/_internal/delegation.py
test/lib/ansible_test/_internal/diff.py
test/lib/ansible_test/_internal/docker_util.py
test/lib/ansible_test/_internal/encoding.py
test/lib/ansible_test/_internal/executor.py
test/lib/ansible_test/_internal/git.py
test/lib/ansible_test/_internal/host_configs.py
test/lib/ansible_test/_internal/host_profiles.py
test/lib/ansible_test/_internal/http.py
test/lib/ansible_test/_internal/init.py
test/lib/ansible_test/_internal/inventory.py
test/lib/ansible_test/_internal/io.py
test/lib/ansible_test/_internal/junit_xml.py
test/lib/ansible_test/_internal/locale_util.py
test/lib/ansible_test/_internal/metadata.py
test/lib/ansible_test/_internal/payload.py
test/lib/ansible_test/_internal/provisioning.py
test/lib/ansible_test/_internal/pypi_proxy.py
test/lib/ansible_test/_internal/python_requirements.py
test/lib/ansible_test/_internal/ssh.py
test/lib/ansible_test/_internal/target.py
test/lib/ansible_test/_internal/test.py
test/lib/ansible_test/_internal/thread.py
test/lib/ansible_test/_internal/timeout.py
test/lib/ansible_test/_internal/util.py
test/lib/ansible_test/_internal/util_common.py
test/lib/ansible_test/_internal/venv.py
test/lib/ansible_test/_internal/ci/__init__.py
test/lib/ansible_test/_internal/ci/azp.py
test/lib/ansible_test/_internal/ci/local.py
test/lib/ansible_test/_internal/classification/__init__.py
test/lib/ansible_test/_internal/classification/common.py
test/lib/ansible_test/_internal/classification/csharp.py
test/lib/ansible_test/_internal/classification/powershell.py
test/lib/ansible_test/_internal/classification/python.py
test/lib/ansible_test/_internal/cli/__init__.py
test/lib/ansible_test/_internal/cli/actions.py
test/lib/ansible_test/_internal/cli/compat.py
test/lib/ansible_test/_internal/cli/completers.py
test/lib/ansible_test/_internal/cli/converters.py
test/lib/ansible_test/_internal/cli/environments.py
test/lib/ansible_test/_internal/cli/epilog.py
test/lib/ansible_test/_internal/cli/argparsing/__init__.py
test/lib/ansible_test/_internal/cli/argparsing/actions.py
test/lib/ansible_test/_internal/cli/argparsing/argcompletion.py
test/lib/ansible_test/_internal/cli/argparsing/parsers.py
test/lib/ansible_test/_internal/cli/commands/__init__.py
test/lib/ansible_test/_internal/cli/commands/env.py
test/lib/ansible_test/_internal/cli/commands/sanity.py
test/lib/ansible_test/_internal/cli/commands/shell.py
test/lib/ansible_test/_internal/cli/commands/units.py
test/lib/ansible_test/_internal/cli/commands/coverage/__init__.py
test/lib/ansible_test/_internal/cli/commands/coverage/combine.py
test/lib/ansible_test/_internal/cli/commands/coverage/erase.py
test/lib/ansible_test/_internal/cli/commands/coverage/html.py
test/lib/ansible_test/_internal/cli/commands/coverage/report.py
test/lib/ansible_test/_internal/cli/commands/coverage/xml.py
test/lib/ansible_test/_internal/cli/commands/coverage/analyze/__init__.py
test/lib/ansible_test/_internal/cli/commands/coverage/analyze/targets/__init__.py
test/lib/ansible_test/_internal/cli/commands/coverage/analyze/targets/combine.py
test/lib/ansible_test/_internal/cli/commands/coverage/analyze/targets/expand.py
test/lib/ansible_test/_internal/cli/commands/coverage/analyze/targets/filter.py
test/lib/ansible_test/_internal/cli/commands/coverage/analyze/targets/generate.py
test/lib/ansible_test/_internal/cli/commands/coverage/analyze/targets/missing.py
test/lib/ansible_test/_internal/cli/commands/integration/__init__.py
test/lib/ansible_test/_internal/cli/commands/integration/network.py
test/lib/ansible_test/_internal/cli/commands/integration/posix.py
test/lib/ansible_test/_internal/cli/commands/integration/windows.py
test/lib/ansible_test/_internal/cli/parsers/__init__.py
test/lib/ansible_test/_internal/cli/parsers/base_argument_parsers.py
test/lib/ansible_test/_internal/cli/parsers/helpers.py
test/lib/ansible_test/_internal/cli/parsers/host_config_parsers.py
test/lib/ansible_test/_internal/cli/parsers/key_value_parsers.py
test/lib/ansible_test/_internal/cli/parsers/value_parsers.py
test/lib/ansible_test/_internal/commands/__init__.py
test/lib/ansible_test/_internal/commands/coverage/__init__.py
test/lib/ansible_test/_internal/commands/coverage/combine.py
test/lib/ansible_test/_internal/commands/coverage/erase.py
test/lib/ansible_test/_internal/commands/coverage/html.py
test/lib/ansible_test/_internal/commands/coverage/report.py
test/lib/ansible_test/_internal/commands/coverage/xml.py
test/lib/ansible_test/_internal/commands/coverage/analyze/__init__.py
test/lib/ansible_test/_internal/commands/coverage/analyze/targets/__init__.py
test/lib/ansible_test/_internal/commands/coverage/analyze/targets/combine.py
test/lib/ansible_test/_internal/commands/coverage/analyze/targets/expand.py
test/lib/ansible_test/_internal/commands/coverage/analyze/targets/filter.py
test/lib/ansible_test/_internal/commands/coverage/analyze/targets/generate.py
test/lib/ansible_test/_internal/commands/coverage/analyze/targets/missing.py
test/lib/ansible_test/_internal/commands/env/__init__.py
test/lib/ansible_test/_internal/commands/integration/__init__.py
test/lib/ansible_test/_internal/commands/integration/coverage.py
test/lib/ansible_test/_internal/commands/integration/filters.py
test/lib/ansible_test/_internal/commands/integration/network.py
test/lib/ansible_test/_internal/commands/integration/posix.py
test/lib/ansible_test/_internal/commands/integration/windows.py
test/lib/ansible_test/_internal/commands/integration/cloud/__init__.py
test/lib/ansible_test/_internal/commands/integration/cloud/acme.py
test/lib/ansible_test/_internal/commands/integration/cloud/aws.py
test/lib/ansible_test/_internal/commands/integration/cloud/azure.py
test/lib/ansible_test/_internal/commands/integration/cloud/cloudscale.py
test/lib/ansible_test/_internal/commands/integration/cloud/cs.py
test/lib/ansible_test/_internal/commands/integration/cloud/digitalocean.py
test/lib/ansible_test/_internal/commands/integration/cloud/galaxy.py
test/lib/ansible_test/_internal/commands/integration/cloud/gcp.py
test/lib/ansible_test/_internal/commands/integration/cloud/hcloud.py
test/lib/ansible_test/_internal/commands/integration/cloud/httptester.py
test/lib/ansible_test/_internal/commands/integration/cloud/nios.py
test/lib/ansible_test/_internal/commands/integration/cloud/opennebula.py
test/lib/ansible_test/_internal/commands/integration/cloud/openshift.py
test/lib/ansible_test/_internal/commands/integration/cloud/scaleway.py
test/lib/ansible_test/_internal/commands/integration/cloud/vcenter.py
test/lib/ansible_test/_internal/commands/integration/cloud/vultr.py
test/lib/ansible_test/_internal/commands/sanity/__init__.py
test/lib/ansible_test/_internal/commands/sanity/ansible_doc.py
test/lib/ansible_test/_internal/commands/sanity/bin_symlinks.py
test/lib/ansible_test/_internal/commands/sanity/compile.py
test/lib/ansible_test/_internal/commands/sanity/ignores.py
test/lib/ansible_test/_internal/commands/sanity/import.py
test/lib/ansible_test/_internal/commands/sanity/integration_aliases.py
test/lib/ansible_test/_internal/commands/sanity/pep8.py
test/lib/ansible_test/_internal/commands/sanity/pslint.py
test/lib/ansible_test/_internal/commands/sanity/pylint.py
test/lib/ansible_test/_internal/commands/sanity/shellcheck.py
test/lib/ansible_test/_internal/commands/sanity/validate_modules.py
test/lib/ansible_test/_internal/commands/sanity/yamllint.py
test/lib/ansible_test/_internal/commands/shell/__init__.py
test/lib/ansible_test/_internal/commands/units/__init__.py
test/lib/ansible_test/_internal/compat/__init__.py
test/lib/ansible_test/_internal/compat/packaging.py
test/lib/ansible_test/_internal/compat/yaml.py
test/lib/ansible_test/_internal/dev/__init__.py
test/lib/ansible_test/_internal/dev/container_probe.py
test/lib/ansible_test/_internal/provider/__init__.py
test/lib/ansible_test/_internal/provider/layout/__init__.py
test/lib/ansible_test/_internal/provider/layout/ansible.py
test/lib/ansible_test/_internal/provider/layout/collection.py
test/lib/ansible_test/_internal/provider/layout/unsupported.py
test/lib/ansible_test/_internal/provider/source/__init__.py
test/lib/ansible_test/_internal/provider/source/git.py
test/lib/ansible_test/_internal/provider/source/installed.py
test/lib/ansible_test/_internal/provider/source/unsupported.py
test/lib/ansible_test/_internal/provider/source/unversioned.py
test/lib/ansible_test/_util/__init__.py
test/lib/ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.json
test/lib/ansible_test/_util/controller/sanity/code-smell/action-plugin-docs.py
test/lib/ansible_test/_util/controller/sanity/code-smell/changelog.json
test/lib/ansible_test/_util/controller/sanity/code-smell/changelog.py
test/lib/ansible_test/_util/controller/sanity/code-smell/empty-init.json
test/lib/ansible_test/_util/controller/sanity/code-smell/empty-init.py
test/lib/ansible_test/_util/controller/sanity/code-smell/line-endings.json
test/lib/ansible_test/_util/controller/sanity/code-smell/line-endings.py
test/lib/ansible_test/_util/controller/sanity/code-smell/no-assert.json
test/lib/ansible_test/_util/controller/sanity/code-smell/no-assert.py
test/lib/ansible_test/_util/controller/sanity/code-smell/no-get-exception.json
test/lib/ansible_test/_util/controller/sanity/code-smell/no-get-exception.py
test/lib/ansible_test/_util/controller/sanity/code-smell/no-illegal-filenames.json
test/lib/ansible_test/_util/controller/sanity/code-smell/no-illegal-filenames.py
test/lib/ansible_test/_util/controller/sanity/code-smell/no-smart-quotes.json
test/lib/ansible_test/_util/controller/sanity/code-smell/no-smart-quotes.py
test/lib/ansible_test/_util/controller/sanity/code-smell/replace-urlopen.json
test/lib/ansible_test/_util/controller/sanity/code-smell/replace-urlopen.py
test/lib/ansible_test/_util/controller/sanity/code-smell/runtime-metadata.json
test/lib/ansible_test/_util/controller/sanity/code-smell/runtime-metadata.py
test/lib/ansible_test/_util/controller/sanity/code-smell/shebang.json
test/lib/ansible_test/_util/controller/sanity/code-smell/shebang.py
test/lib/ansible_test/_util/controller/sanity/code-smell/symlinks.json
test/lib/ansible_test/_util/controller/sanity/code-smell/symlinks.py
test/lib/ansible_test/_util/controller/sanity/code-smell/use-argspec-type-path.json
test/lib/ansible_test/_util/controller/sanity/code-smell/use-argspec-type-path.py
test/lib/ansible_test/_util/controller/sanity/code-smell/use-compat-six.json
test/lib/ansible_test/_util/controller/sanity/code-smell/use-compat-six.py
test/lib/ansible_test/_util/controller/sanity/code-smell/changelog/sphinx.py
test/lib/ansible_test/_util/controller/sanity/integration-aliases/yaml_to_json.py
test/lib/ansible_test/_util/controller/sanity/pep8/current-ignore.txt
test/lib/ansible_test/_util/controller/sanity/pslint/pslint.ps1
test/lib/ansible_test/_util/controller/sanity/pslint/settings.psd1
test/lib/ansible_test/_util/controller/sanity/pylint/config/ansible-test-target.cfg
test/lib/ansible_test/_util/controller/sanity/pylint/config/ansible-test.cfg
test/lib/ansible_test/_util/controller/sanity/pylint/config/code-smell.cfg
test/lib/ansible_test/_util/controller/sanity/pylint/config/collection.cfg
test/lib/ansible_test/_util/controller/sanity/pylint/config/default.cfg
test/lib/ansible_test/_util/controller/sanity/pylint/plugins/deprecated_calls.py
test/lib/ansible_test/_util/controller/sanity/pylint/plugins/deprecated_comment.py
test/lib/ansible_test/_util/controller/sanity/pylint/plugins/hide_unraisable.py
test/lib/ansible_test/_util/controller/sanity/pylint/plugins/string_format.py
test/lib/ansible_test/_util/controller/sanity/pylint/plugins/unwanted.py
test/lib/ansible_test/_util/controller/sanity/shellcheck/exclude.txt
test/lib/ansible_test/_util/controller/sanity/validate-modules/validate.py
test/lib/ansible_test/_util/controller/sanity/validate-modules/validate_modules/__init__.py
test/lib/ansible_test/_util/controller/sanity/validate-modules/validate_modules/main.py
test/lib/ansible_test/_util/controller/sanity/validate-modules/validate_modules/module_args.py
test/lib/ansible_test/_util/controller/sanity/validate-modules/validate_modules/ps_argspec.ps1
test/lib/ansible_test/_util/controller/sanity/validate-modules/validate_modules/schema.py
test/lib/ansible_test/_util/controller/sanity/validate-modules/validate_modules/utils.py
test/lib/ansible_test/_util/controller/sanity/yamllint/yamllinter.py
test/lib/ansible_test/_util/controller/sanity/yamllint/config/default.yml
test/lib/ansible_test/_util/controller/sanity/yamllint/config/modules.yml
test/lib/ansible_test/_util/controller/sanity/yamllint/config/plugins.yml
test/lib/ansible_test/_util/controller/tools/collection_detail.py
test/lib/ansible_test/_util/controller/tools/coverage_stub.ps1
test/lib/ansible_test/_util/controller/tools/yaml_to_json.py
test/lib/ansible_test/_util/target/__init__.py
test/lib/ansible_test/_util/target/cli/ansible_test_cli_stub.py
test/lib/ansible_test/_util/target/common/constants.py
test/lib/ansible_test/_util/target/injector/python.py
test/lib/ansible_test/_util/target/injector/virtualenv.sh
test/lib/ansible_test/_util/target/pytest/plugins/ansible_forked.py
test/lib/ansible_test/_util/target/pytest/plugins/ansible_pytest_collections.py
test/lib/ansible_test/_util/target/pytest/plugins/ansible_pytest_coverage.py
test/lib/ansible_test/_util/target/sanity/compile/compile.py
test/lib/ansible_test/_util/target/sanity/import/importer.py
test/lib/ansible_test/_util/target/setup/bootstrap.sh
test/lib/ansible_test/_util/target/setup/check_systemd_cgroup_v1.sh
test/lib/ansible_test/_util/target/setup/probe_cgroups.py
test/lib/ansible_test/_util/target/setup/quiet_pip.py
test/lib/ansible_test/_util/target/setup/requirements.py
test/lib/ansible_test/_util/target/tools/virtualenvcheck.py
test/lib/ansible_test/_util/target/tools/yamlcheck.py
test/lib/ansible_test/config/cloud-config-aws.ini.template
test/lib/ansible_test/config/cloud-config-azure.ini.template
test/lib/ansible_test/config/cloud-config-cloudscale.ini.template
test/lib/ansible_test/config/cloud-config-cs.ini.template
test/lib/ansible_test/config/cloud-config-gcp.ini.template
test/lib/ansible_test/config/cloud-config-hcloud.ini.template
test/lib/ansible_test/config/cloud-config-opennebula.ini.template
test/lib/ansible_test/config/cloud-config-openshift.kubeconfig.template
test/lib/ansible_test/config/cloud-config-scaleway.ini.template
test/lib/ansible_test/config/cloud-config-vcenter.ini.template
test/lib/ansible_test/config/cloud-config-vultr.ini.template
test/lib/ansible_test/config/config.yml
test/lib/ansible_test/config/inventory.networking.template
test/lib/ansible_test/config/inventory.winrm.template
test/sanity/ignore.txt
test/sanity/code-smell/ansible-requirements.json
test/sanity/code-smell/ansible-requirements.py
test/sanity/code-smell/black.json
test/sanity/code-smell/black.py
test/sanity/code-smell/black.requirements.in
test/sanity/code-smell/black.requirements.txt
test/sanity/code-smell/boilerplate.json
test/sanity/code-smell/boilerplate.py
test/sanity/code-smell/deprecated-config.json
test/sanity/code-smell/deprecated-config.py
test/sanity/code-smell/deprecated-config.requirements.in
test/sanity/code-smell/deprecated-config.requirements.txt
test/sanity/code-smell/mypy.json
test/sanity/code-smell/mypy.py
test/sanity/code-smell/mypy.requirements.in
test/sanity/code-smell/mypy.requirements.txt
test/sanity/code-smell/no-unwanted-characters.json
test/sanity/code-smell/no-unwanted-characters.py
test/sanity/code-smell/no-unwanted-files.json
test/sanity/code-smell/no-unwanted-files.py
test/sanity/code-smell/obsolete-files.json
test/sanity/code-smell/obsolete-files.py
test/sanity/code-smell/package-data.json
test/sanity/code-smell/package-data.py
test/sanity/code-smell/package-data.requirements.in
test/sanity/code-smell/package-data.requirements.txt
test/sanity/code-smell/pymarkdown.config.json
test/sanity/code-smell/pymarkdown.json
test/sanity/code-smell/pymarkdown.py
test/sanity/code-smell/pymarkdown.requirements.in
test/sanity/code-smell/pymarkdown.requirements.txt
test/sanity/code-smell/release-names.json
test/sanity/code-smell/release-names.py
test/sanity/code-smell/required-and-default-attributes.json
test/sanity/code-smell/required-and-default-attributes.py
test/sanity/code-smell/skip.txt
test/sanity/code-smell/test-constraints.json
test/sanity/code-smell/test-constraints.py
test/sanity/code-smell/update-bundled.json
test/sanity/code-smell/update-bundled.py
test/sanity/code-smell/update-bundled.requirements.in
test/sanity/code-smell/update-bundled.requirements.txt
test/sanity/code-smell/mypy/ansible-core.ini
test/sanity/code-smell/mypy/ansible-test.ini
test/sanity/code-smell/mypy/packaging.ini
test/support/README.md
test/support/integration/plugins/modules/pkgng.py
test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/action/cli_config.py
test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/action/net_get.py
test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/action/net_put.py
test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/action/network.py
test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/connection/network_cli.py
test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/connection/persistent.py
test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/doc_fragments/connection_persistent.py
test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/compat/ipaddress.py
test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/config.py
test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/netconf.py
test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/network.py
test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/parsing.py
test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/utils.py
test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/cfg/base.py
test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/module_utils/network/common/facts/facts.py
test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/modules/cli_config.py
test/support/network-integration/collections/ansible_collections/ansible/netcommon/plugins/plugin_utils/connection_base.py
test/support/network-integration/collections/ansible_collections/cisco/ios/plugins/action/ios.py
test/support/network-integration/collections/ansible_collections/cisco/ios/plugins/cliconf/ios.py
test/support/network-integration/collections/ansible_collections/cisco/ios/plugins/doc_fragments/ios.py
test/support/network-integration/collections/ansible_collections/cisco/ios/plugins/module_utils/network/ios/ios.py
test/support/network-integration/collections/ansible_collections/cisco/ios/plugins/modules/ios_command.py
test/support/network-integration/collections/ansible_collections/cisco/ios/plugins/modules/ios_config.py
test/support/network-integration/collections/ansible_collections/cisco/ios/plugins/terminal/ios.py
test/support/windows-integration/collections/ansible_collections/ansible/windows/plugins/action/win_copy.py
test/support/windows-integration/collections/ansible_collections/ansible/windows/plugins/action/win_reboot.py
test/support/windows-integration/collections/ansible_collections/ansible/windows/plugins/module_utils/WebRequest.psm1
test/support/windows-integration/collections/ansible_collections/ansible/windows/plugins/modules/async_status.ps1
test/support/windows-integration/collections/ansible_collections/ansible/windows/plugins/modules/win_acl.ps1
test/support/windows-integration/collections/ansible_collections/ansible/windows/plugins/modules/win_acl.py
test/support/windows-integration/collections/ansible_collections/ansible/windows/plugins/modules/win_copy.ps1
test/support/windows-integration/collections/ansible_collections/ansible/windows/plugins/modules/win_copy.py
test/support/windows-integration/collections/ansible_collections/ansible/windows/plugins/modules/win_file.ps1
test/support/windows-integration/collections/ansible_collections/ansible/windows/plugins/modules/win_file.py
test/support/windows-integration/collections/ansible_collections/ansible/windows/plugins/modules/win_ping.ps1
test/support/windows-integration/collections/ansible_collections/ansible/windows/plugins/modules/win_ping.py
test/support/windows-integration/collections/ansible_collections/ansible/windows/plugins/modules/win_shell.ps1
test/support/windows-integration/collections/ansible_collections/ansible/windows/plugins/modules/win_shell.py
test/support/windows-integration/collections/ansible_collections/ansible/windows/plugins/modules/win_stat.ps1
test/support/windows-integration/collections/ansible_collections/ansible/windows/plugins/modules/win_stat.py
test/support/windows-integration/collections/ansible_collections/ansible/windows/plugins/modules/win_uri.ps1
test/support/windows-integration/collections/ansible_collections/ansible/windows/plugins/modules/win_uri.py
test/support/windows-integration/collections/ansible_collections/ansible/windows/plugins/plugin_utils/_quote.py
test/support/windows-integration/collections/ansible_collections/ansible/windows/plugins/plugin_utils/_reboot.py
test/support/windows-integration/plugins/action/win_copy.py
test/support/windows-integration/plugins/action/win_reboot.py
test/support/windows-integration/plugins/action/win_template.py
test/support/windows-integration/plugins/become/runas.py
test/support/windows-integration/plugins/module_utils/Ansible.Service.cs
test/support/windows-integration/plugins/modules/async_status.ps1
test/support/windows-integration/plugins/modules/setup.ps1
test/support/windows-integration/plugins/modules/slurp.ps1
test/support/windows-integration/plugins/modules/win_acl.ps1
test/support/windows-integration/plugins/modules/win_acl.py
test/support/windows-integration/plugins/modules/win_certificate_store.ps1
test/support/windows-integration/plugins/modules/win_certificate_store.py
test/support/windows-integration/plugins/modules/win_command.ps1
test/support/windows-integration/plugins/modules/win_command.py
test/support/windows-integration/plugins/modules/win_copy.ps1
test/support/windows-integration/plugins/modules/win_copy.py
test/support/windows-integration/plugins/modules/win_file.ps1
test/support/windows-integration/plugins/modules/win_file.py
test/support/windows-integration/plugins/modules/win_get_url.ps1
test/support/windows-integration/plugins/modules/win_get_url.py
test/support/windows-integration/plugins/modules/win_lineinfile.ps1
test/support/windows-integration/plugins/modules/win_lineinfile.py
test/support/windows-integration/plugins/modules/win_ping.ps1
test/support/windows-integration/plugins/modules/win_ping.py
test/support/windows-integration/plugins/modules/win_reboot.py
test/support/windows-integration/plugins/modules/win_regedit.ps1
test/support/windows-integration/plugins/modules/win_regedit.py
test/support/windows-integration/plugins/modules/win_shell.ps1
test/support/windows-integration/plugins/modules/win_shell.py
test/support/windows-integration/plugins/modules/win_stat.ps1
test/support/windows-integration/plugins/modules/win_stat.py
test/support/windows-integration/plugins/modules/win_tempfile.ps1
test/support/windows-integration/plugins/modules/win_user.ps1
test/support/windows-integration/plugins/modules/win_user.py
test/support/windows-integration/plugins/modules/win_user_right.ps1
test/support/windows-integration/plugins/modules/win_user_right.py
test/support/windows-integration/plugins/modules/win_wait_for.ps1
test/support/windows-integration/plugins/modules/win_wait_for.py
test/support/windows-integration/plugins/modules/win_whoami.ps1
test/support/windows-integration/plugins/modules/win_whoami.py
test/units/__init__.py
test/units/conftest.py
test/units/controller_only_conftest.py
test/units/requirements.txt
test/units/test_context.py
test/units/test_no_tty.py
test/units/_internal/__init__.py
test/units/_internal/test_locking.py
test/units/_internal/_datatag/__init__.py
test/units/_internal/_datatag/test_tags.py
test/units/_internal/_json/__init__.py
test/units/_internal/_json/test_legacy_encoder.py
test/units/_internal/templating/__init__.py
test/units/_internal/templating/conftest.py
test/units/_internal/templating/test_access.py
test/units/_internal/templating/test_common_.py
test/units/_internal/templating/test_datatag.py
test/units/_internal/templating/test_jinja_bits.py
test/units/_internal/templating/test_jinja_plugins.py
test/units/_internal/templating/test_lazy_containers.py
test/units/_internal/templating/test_templar.py
test/units/_internal/templating/test_template_utilities.py
test/units/_internal/templating/test_utils.py
test/units/_internal/templating/fixtures/__init__.py
test/units/_internal/templating/fixtures/valid_collection/__init__.py
test/units/_internal/templating/fixtures/valid_collection/ansible_collections/__init__.py
test/units/_internal/templating/fixtures/valid_collection/ansible_collections/valid/__init__.py
test/units/_internal/templating/fixtures/valid_collection/ansible_collections/valid/also_valid/__init__.py
test/units/_internal/templating/fixtures/valid_collection/ansible_collections/valid/also_valid/plugins/__init__.py
test/units/_internal/templating/fixtures/valid_collection/ansible_collections/valid/also_valid/plugins/filter/__init__.py
test/units/_internal/templating/fixtures/valid_collection/ansible_collections/valid/also_valid/plugins/filter/correct.py
test/units/_internal/templating/fixtures/valid_collection/ansible_collections/valid/also_valid/plugins/filter/get_filters_error.py
test/units/_internal/templating/fixtures/valid_collection/ansible_collections/valid/also_valid/plugins/filter/load_error.py
test/units/_internal/templating/fixtures/valid_collection/ansible_collections/valid/also_valid/plugins/lookup/__init__.py
test/units/_internal/templating/fixtures/valid_collection/ansible_collections/valid/also_valid/plugins/lookup/also_also_valid.py
test/units/_internal/templating/fixtures/valid_collection/ansible_collections/valid/also_valid/plugins/lookup/load_error.py
test/units/_internal/templating/fixtures/valid_collection/ansible_collections/valid/also_valid/plugins/lookup/runtime_error.py
test/units/_vendor/__init__.py
test/units/_vendor/test_vendor.py
test/units/ansible_test/__init__.py
test/units/ansible_test/conftest.py
test/units/ansible_test/test_diff.py
test/units/ansible_test/_internal/__init__.py
test/units/ansible_test/_internal/test_util.py
test/units/ansible_test/ci/__init__.py
test/units/ansible_test/ci/test_azp.py
test/units/ansible_test/ci/util.py
test/units/ansible_test/diff/add_binary_file.diff
test/units/ansible_test/diff/add_text_file.diff
test/units/ansible_test/diff/add_trailing_newline.diff
test/units/ansible_test/diff/add_two_text_files.diff
test/units/ansible_test/diff/context_no_trailing_newline.diff
test/units/ansible_test/diff/multiple_context_lines.diff
test/units/ansible_test/diff/parse_delete.diff
test/units/ansible_test/diff/parse_rename.diff
test/units/ansible_test/diff/remove_trailing_newline.diff
test/units/cli/__init__.py
test/units/cli/test_adhoc.py
test/units/cli/test_cli.py
test/units/cli/test_console.py
test/units/cli/test_doc.py
test/units/cli/test_galaxy.py
test/units/cli/test_playbook.py
test/units/cli/test_vault.py
test/units/cli/arguments/test_option_helpers.py
test/units/cli/galaxy/test_collection_extract_tar.py
test/units/cli/galaxy/test_display_collection.py
test/units/cli/galaxy/test_display_header.py
test/units/cli/galaxy/test_display_role.py
test/units/cli/galaxy/test_execute_list.py
test/units/cli/galaxy/test_execute_list_collection.py
test/units/cli/galaxy/test_get_collection_widths.py
test/units/cli/test_data/collection_skeleton/README.md
test/units/cli/test_data/collection_skeleton/galaxy.yml.j2
test/units/cli/test_data/collection_skeleton/docs/My Collection.md
test/units/cli/test_data/collection_skeleton/playbooks/main.yml
test/units/cli/test_data/collection_skeleton/playbooks/templates/test.conf.j2
test/units/cli/test_data/collection_skeleton/playbooks/templates/subfolder/test.conf.j2
test/units/cli/test_data/collection_skeleton/plugins/action/.git_keep
test/units/cli/test_data/collection_skeleton/plugins/filter/.git_keep
test/units/cli/test_data/collection_skeleton/plugins/inventory/.git_keep
test/units/cli/test_data/collection_skeleton/plugins/lookup/.git_keep
test/units/cli/test_data/collection_skeleton/plugins/module_utils/.git_keep
test/units/cli/test_data/collection_skeleton/plugins/modules/.git_keep
test/units/cli/test_data/collection_skeleton/roles/common/tasks/main.yml.j2
test/units/cli/test_data/collection_skeleton/roles/common/templates/test.conf.j2
test/units/cli/test_data/collection_skeleton/roles/common/templates/subfolder/test.conf.j2
test/units/cli/test_data/role_skeleton/README.md
test/units/cli/test_data/role_skeleton/inventory
test/units/cli/test_data/role_skeleton/defaults/main.yml.j2
test/units/cli/test_data/role_skeleton/files/.git_keep
test/units/cli/test_data/role_skeleton/handlers/main.yml.j2
test/units/cli/test_data/role_skeleton/meta/main.yml.j2
test/units/cli/test_data/role_skeleton/tasks/main.yml.j2
test/units/cli/test_data/role_skeleton/templates/.git_keep
test/units/cli/test_data/role_skeleton/templates/test.conf.j2
test/units/cli/test_data/role_skeleton/templates/subfolder/test.conf.j2
test/units/cli/test_data/role_skeleton/templates_extra/templates.txt.j2
test/units/cli/test_data/role_skeleton/tests/test.yml.j2
test/units/cli/test_data/role_skeleton/vars/main.yml.j2
test/units/config/__init__.py
test/units/config/test.cfg
test/units/config/test.yml
test/units/config/test2.cfg
test/units/config/test3.cfg
test/units/config/test_manager.py
test/units/config/manager/__init__.py
test/units/config/manager/test_find_ini_config_file.py
test/units/errors/__init__.py
test/units/errors/test_errors.py
test/units/errors/test_handler.py
test/units/errors/test_utils.py
test/units/errors/fixtures/inputs/empty_file.txt
test/units/errors/fixtures/inputs/file_with_tabs.txt
test/units/errors/fixtures/inputs/long_file.txt
test/units/errors/fixtures/inputs/one_line_file.txt
test/units/errors/fixtures/inputs/short_file.txt
test/units/errors/fixtures/inputs/short_file_missing_trailing_newline.txt
test/units/errors/fixtures/outputs/empty_file_unavailable.txt
test/units/errors/fixtures/outputs/file_with_tabs_replaced_left_marker.txt
test/units/errors/fixtures/outputs/long_file_last_column_right_marker.txt
test/units/errors/fixtures/outputs/nonexistent.txt
test/units/errors/fixtures/outputs/short_file_last_column_right_marker.txt
test/units/errors/fixtures/outputs/short_file_left_marker.txt
test/units/errors/fixtures/outputs/short_file_long_line_truncated_past_target.txt
test/units/errors/fixtures/outputs/short_file_missing_trailing_newline_left_marker.txt
test/units/errors/fixtures/outputs/short_file_no_column.txt
test/units/errors/fixtures/outputs/short_file_no_column_overflowed.txt
test/units/errors/fixtures/outputs/short_file_no_context_left_marker.txt
test/units/errors/fixtures/outputs/short_file_no_line.txt
test/units/errors/fixtures/outputs/short_file_overflowed_col.txt
test/units/errors/fixtures/outputs/short_file_overflowed_line.txt
test/units/errors/fixtures/outputs/short_file_truncated_target.txt
test/units/errors/fixtures/outputs/short_file_truncated_target_last_displayed_char.txt
test/units/errors/fixtures/outputs/short_file_underflowed_col.txt
test/units/errors/fixtures/outputs/short_file_underflowed_line.txt
test/units/executor/__init__.py
test/units/executor/test_play_iterator.py
test/units/executor/test_playbook_executor.py
test/units/executor/test_task_executor.py
test/units/executor/test_task_result.py
test/units/executor/module_common/conftest.py
test/units/executor/module_common/test_module_common.py
test/units/executor/module_common/test_recursive_finder.py
test/units/galaxy/__init__.py
test/units/galaxy/test_api.py
test/units/galaxy/test_collection.py
test/units/galaxy/test_collection_dataclasses.py
test/units/galaxy/test_collection_install.py
test/units/galaxy/test_role_install.py
test/units/galaxy/test_role_requirements.py
test/units/galaxy/test_token.py
test/units/galaxy/test_user_agent.py
test/units/inventory/__init__.py
test/units/inventory/test_data.py
test/units/inventory/test_group.py
test/units/inventory/test_host.py
test/units/inventory_test_data/group_vars/noparse/all.yml~
test/units/inventory_test_data/group_vars/noparse/file.txt
test/units/inventory_test_data/group_vars/parse/all.yml
test/units/mock/__init__.py
test/units/mock/custom_types.py
test/units/mock/loader.py
test/units/mock/messages.py
test/units/mock/module.py
test/units/mock/path.py
test/units/mock/vault_helper.py
test/units/mock/yaml_helper.py
test/units/module_utils/__init__.py
test/units/module_utils/conftest.py
test/units/module_utils/test_api.py
test/units/module_utils/test_connection.py
test/units/module_utils/test_distro.py
test/units/module_utils/test_text.py
test/units/module_utils/_internal/__init__.py
test/units/module_utils/_internal/test_deprecator.py
test/units/module_utils/_internal/_concurrent/__init__.py
test/units/module_utils/_internal/_concurrent/test_daemon_threading.py
test/units/module_utils/_internal/_concurrent/test_futures.py
test/units/module_utils/_internal/_patches/__init__.py
test/units/module_utils/_internal/_patches/test_dataclass_annotation_patch.py
test/units/module_utils/_internal/_patches/test_patches.py
test/units/module_utils/_internal/_patches/test_socket_patch.py
test/units/module_utils/_internal/_patches/test_sys_intern_patch.py
test/units/module_utils/basic/__init__.py
test/units/module_utils/basic/test__log_invocation.py
test/units/module_utils/basic/test__symbolic_mode_to_octal.py
test/units/module_utils/basic/test_argument_spec.py
test/units/module_utils/basic/test_atomic_move.py
test/units/module_utils/basic/test_command_nonexisting.py
test/units/module_utils/basic/test_dict_converters.py
test/units/module_utils/basic/test_exit_json.py
test/units/module_utils/basic/test_filesystem.py
test/units/module_utils/basic/test_get_available_hash_algorithms.py
test/units/module_utils/basic/test_get_file_attributes.py
test/units/module_utils/basic/test_get_module_path.py
test/units/module_utils/basic/test_heuristic_log_sanitize.py
test/units/module_utils/basic/test_imports.py
test/units/module_utils/basic/test_log.py
test/units/module_utils/basic/test_no_log.py
test/units/module_utils/basic/test_platform_distribution.py
test/units/module_utils/basic/test_run_command.py
test/units/module_utils/basic/test_safe_eval.py
test/units/module_utils/basic/test_sanitize_keys.py
test/units/module_utils/basic/test_selinux.py
test/units/module_utils/basic/test_set_cwd.py
test/units/module_utils/basic/test_set_mode_if_different.py
test/units/module_utils/basic/test_tmpdir.py
test/units/module_utils/common/__init__.py
test/units/module_utils/common/test_collections.py
test/units/module_utils/common/test_dict_transformations.py
test/units/module_utils/common/test_json.py
test/units/module_utils/common/test_locale.py
test/units/module_utils/common/test_network.py
test/units/module_utils/common/test_sys_info.py
test/units/module_utils/common/test_utils.py
test/units/module_utils/common/test_yaml.py
test/units/module_utils/common/arg_spec/__init__.py
test/units/module_utils/common/arg_spec/test_aliases.py
test/units/module_utils/common/arg_spec/test_module_validate.py
test/units/module_utils/common/arg_spec/test_sub_spec.py
test/units/module_utils/common/arg_spec/test_validate_invalid.py
test/units/module_utils/common/arg_spec/test_validate_valid.py
test/units/module_utils/common/parameters/test_check_arguments.py
test/units/module_utils/common/parameters/test_handle_aliases.py
test/units/module_utils/common/parameters/test_list_deprecations.py
test/units/module_utils/common/parameters/test_list_no_log_values.py
test/units/module_utils/common/process/test_get_bin_path.py
test/units/module_utils/common/text/converters/test_container_to_bytes.py
test/units/module_utils/common/text/converters/test_container_to_text.py
test/units/module_utils/common/text/converters/test_jsonify.py
test/units/module_utils/common/text/converters/test_to_str.py
test/units/module_utils/common/text/formatters/test_bytes_to_human.py
test/units/module_utils/common/text/formatters/test_human_to_bytes.py
test/units/module_utils/common/text/formatters/test_lenient_lowercase.py
test/units/module_utils/common/validation/test_check_missing_parameters.py
test/units/module_utils/common/validation/test_check_mutually_exclusive.py
test/units/module_utils/common/validation/test_check_required_arguments.py
test/units/module_utils/common/validation/test_check_required_by.py
test/units/module_utils/common/validation/test_check_required_if.py
test/units/module_utils/common/validation/test_check_required_one_of.py
test/units/module_utils/common/validation/test_check_required_together.py
test/units/module_utils/common/validation/test_check_type_bits.py
test/units/module_utils/common/validation/test_check_type_bool.py
test/units/module_utils/common/validation/test_check_type_bytes.py
test/units/module_utils/common/validation/test_check_type_dict.py
test/units/module_utils/common/validation/test_check_type_float.py
test/units/module_utils/common/validation/test_check_type_int.py
test/units/module_utils/common/validation/test_check_type_jsonarg.py
test/units/module_utils/common/validation/test_check_type_list.py
test/units/module_utils/common/validation/test_check_type_path.py
test/units/module_utils/common/validation/test_check_type_raw.py
test/units/module_utils/common/validation/test_check_type_str.py
test/units/module_utils/common/validation/test_count_terms.py
test/units/module_utils/common/warnings/test_deprecate.py
test/units/module_utils/common/warnings/test_warn.py
test/units/module_utils/compat/__init__.py
test/units/module_utils/compat/test_datetime.py
test/units/module_utils/datatag/__init__.py
test/units/module_utils/datatag/test_datatag.py
test/units/module_utils/facts/__init__.py
test/units/module_utils/facts/base.py
test/units/module_utils/facts/test_ansible_collector.py
test/units/module_utils/facts/test_collector.py
test/units/module_utils/facts/test_collectors.py
test/units/module_utils/facts/test_date_time.py
test/units/module_utils/facts/test_facts.py
test/units/module_utils/facts/test_sysctl.py
test/units/module_utils/facts/test_timeout.py
test/units/module_utils/facts/test_utils.py
test/units/module_utils/facts/fixtures/findmount_output.txt
test/units/module_utils/facts/fixtures/cpuinfo/aarch64-4cpu-cpuinfo
test/units/module_utils/facts/fixtures/cpuinfo/arm64-4cpu-cpuinfo
test/units/module_utils/facts/fixtures/cpuinfo/armv6-rev7-1cpu-cpuinfo
test/units/module_utils/facts/fixtures/cpuinfo/armv7-rev3-8cpu-cpuinfo
test/units/module_utils/facts/fixtures/cpuinfo/armv7-rev4-4cpu-cpuinfo
test/units/module_utils/facts/fixtures/cpuinfo/ppc64-power7-rhel7-8cpu-cpuinfo
test/units/module_utils/facts/fixtures/cpuinfo/ppc64le-power8-24cpu-cpuinfo
test/units/module_utils/facts/fixtures/cpuinfo/s390x-z13-2cpu-cpuinfo
test/units/module_utils/facts/fixtures/cpuinfo/s390x-z14-64cpu-cpuinfo
test/units/module_utils/facts/fixtures/cpuinfo/sparc-t5-debian-ldom-24vcpu
test/units/module_utils/facts/fixtures/cpuinfo/x86_64-2cpu-cpuinfo
test/units/module_utils/facts/fixtures/cpuinfo/x86_64-4cpu-cpuinfo
test/units/module_utils/facts/fixtures/cpuinfo/x86_64-8cpu-cpuinfo
test/units/module_utils/facts/fixtures/distribution_files/ClearLinux
test/units/module_utils/facts/fixtures/distribution_files/CoreOS
test/units/module_utils/facts/fixtures/distribution_files/LinuxMint
test/units/module_utils/facts/fixtures/distribution_files/Slackware
test/units/module_utils/facts/fixtures/distribution_files/SlackwareCurrent
test/units/module_utils/facts/hardware/__init__.py
test/units/module_utils/facts/hardware/aix_data.py
test/units/module_utils/facts/hardware/linux_data.py
test/units/module_utils/facts/hardware/test_aix_processor.py
test/units/module_utils/facts/hardware/test_darwin_facts.py
test/units/module_utils/facts/hardware/test_linux.py
test/units/module_utils/facts/hardware/test_linux_get_cpu_info.py
test/units/module_utils/facts/hardware/test_sunos_get_uptime_facts.py
test/units/module_utils/facts/hardware/fixtures/sysctl_darwin_intel.txt
test/units/module_utils/facts/hardware/fixtures/sysctl_darwin_silicon.txt
test/units/module_utils/facts/hardware/fixtures/vm_stat_darwin_intel.txt
test/units/module_utils/facts/hardware/fixtures/vm_stat_darwin_silicon.txt
test/units/module_utils/facts/hardware/freebsd/test_get_device_facts.py
test/units/module_utils/facts/hardware/freebsd/fixtures/devices
test/units/module_utils/facts/hardware/freebsd/fixtures/expected_devices
test/units/module_utils/facts/hardware/linux/test_get_sysinfo_facts.py
test/units/module_utils/facts/hardware/linux/fixtures/sysinfo
test/units/module_utils/facts/network/__init__.py
test/units/module_utils/facts/network/test_fc_wwn.py
test/units/module_utils/facts/network/test_generic_bsd.py
test/units/module_utils/facts/network/test_iscsi_get_initiator.py
test/units/module_utils/facts/network/test_locally_reachable_ips.py
test/units/module_utils/facts/other/__init__.py
test/units/module_utils/facts/other/test_facter.py
test/units/module_utils/facts/other/test_ohai.py
test/units/module_utils/facts/system/__init__.py
test/units/module_utils/facts/system/test_cmdline.py
test/units/module_utils/facts/system/test_fips.py
test/units/module_utils/facts/system/test_lsb.py
test/units/module_utils/facts/system/test_pkg_mgr.py
test/units/module_utils/facts/system/test_user.py
test/units/module_utils/facts/system/distribution/__init__.py
test/units/module_utils/facts/system/distribution/conftest.py
test/units/module_utils/facts/system/distribution/test_distribution_files.py
test/units/module_utils/facts/system/distribution/test_distribution_sles4sap.py
test/units/module_utils/facts/system/distribution/test_distribution_version.py
test/units/module_utils/facts/system/distribution/test_parse_distribution_file_ClearLinux.py
test/units/module_utils/facts/system/distribution/test_parse_distribution_file_Slackware.py
test/units/module_utils/facts/system/distribution/fixtures/almalinux_8_3_beta.json
test/units/module_utils/facts/system/distribution/fixtures/alp-dolomite.json
test/units/module_utils/facts/system/distribution/fixtures/amazon_linux_2.json
test/units/module_utils/facts/system/distribution/fixtures/amazon_linux_2016.03.json
test/units/module_utils/facts/system/distribution/fixtures/amazon_linux_2018.03.json
test/units/module_utils/facts/system/distribution/fixtures/amazon_linux_2_karoo.json
test/units/module_utils/facts/system/distribution/fixtures/amazon_linux_release_2.json
test/units/module_utils/facts/system/distribution/fixtures/arch_linux_na.json
test/units/module_utils/facts/system/distribution/fixtures/arch_linux_no_arch-release_na.json
test/units/module_utils/facts/system/distribution/fixtures/archlinux_rolling.json
test/units/module_utils/facts/system/distribution/fixtures/centos_6.7.json
test/units/module_utils/facts/system/distribution/fixtures/centos_8_1.json
test/units/module_utils/facts/system/distribution/fixtures/centos_stream_8.json
test/units/module_utils/facts/system/distribution/fixtures/clearlinux_26580.json
test/units/module_utils/facts/system/distribution/fixtures/clearlinux_28120.json
test/units/module_utils/facts/system/distribution/fixtures/core_os_1911.5.0.json
test/units/module_utils/facts/system/distribution/fixtures/core_os_976.0.0.json
test/units/module_utils/facts/system/distribution/fixtures/cumulus_linux_2.5.4.json
test/units/module_utils/facts/system/distribution/fixtures/cumulus_linux_3.7.3.json
test/units/module_utils/facts/system/distribution/fixtures/debian_10.json
test/units/module_utils/facts/system/distribution/fixtures/debian_7.9.json
test/units/module_utils/facts/system/distribution/fixtures/debian_stretch_sid.json
test/units/module_utils/facts/system/distribution/fixtures/deepin_20.4.json
test/units/module_utils/facts/system/distribution/fixtures/devuan.json
test/units/module_utils/facts/system/distribution/fixtures/dragonfly_5.2.2.json
test/units/module_utils/facts/system/distribution/fixtures/dragonfly_5.6.2.json
test/units/module_utils/facts/system/distribution/fixtures/eurolinux_8.5.json
test/units/module_utils/facts/system/distribution/fixtures/fedora_22.json
test/units/module_utils/facts/system/distribution/fixtures/fedora_25.json
test/units/module_utils/facts/system/distribution/fixtures/fedora_31.json
test/units/module_utils/facts/system/distribution/fixtures/flatcar_3139.2.0.json
test/units/module_utils/facts/system/distribution/fixtures/kali_2019.1.json
test/units/module_utils/facts/system/distribution/fixtures/kde_neon_16.04.json
test/units/module_utils/facts/system/distribution/fixtures/kylin_linux_advanced_server_v10.json
test/units/module_utils/facts/system/distribution/fixtures/linux_mint_18.2.json
test/units/module_utils/facts/system/distribution/fixtures/linux_mint_19.1.json
test/units/module_utils/facts/system/distribution/fixtures/lmde_6.json
test/units/module_utils/facts/system/distribution/fixtures/miracle_linux_9.json
test/units/module_utils/facts/system/distribution/fixtures/netbsd_8.2.json
test/units/module_utils/facts/system/distribution/fixtures/nexenta_3.json
test/units/module_utils/facts/system/distribution/fixtures/nexenta_4.json
test/units/module_utils/facts/system/distribution/fixtures/omnios.json
test/units/module_utils/facts/system/distribution/fixtures/openeuler_20.03.json
test/units/module_utils/facts/system/distribution/fixtures/openindiana.json
test/units/module_utils/facts/system/distribution/fixtures/opensuse-microos-20241205.json
test/units/module_utils/facts/system/distribution/fixtures/opensuse_13.2.json
test/units/module_utils/facts/system/distribution/fixtures/opensuse_leap_15.0.json
test/units/module_utils/facts/system/distribution/fixtures/opensuse_leap_15.1.json
test/units/module_utils/facts/system/distribution/fixtures/opensuse_leap_42.1.json
test/units/module_utils/facts/system/distribution/fixtures/opensuse_tumbleweed_20160917.json
test/units/module_utils/facts/system/distribution/fixtures/osmc.json
test/units/module_utils/facts/system/distribution/fixtures/pardus_19.1.json
test/units/module_utils/facts/system/distribution/fixtures/parrot_4.8.json
test/units/module_utils/facts/system/distribution/fixtures/pop_os_20.04.json
test/units/module_utils/facts/system/distribution/fixtures/redhat_6.7.json
test/units/module_utils/facts/system/distribution/fixtures/redhat_7.2.json
test/units/module_utils/facts/system/distribution/fixtures/redhat_7.7.json
test/units/module_utils/facts/system/distribution/fixtures/rockylinux_8_3.json
test/units/module_utils/facts/system/distribution/fixtures/sl-micro.json
test/units/module_utils/facts/system/distribution/fixtures/sles_11.3.json
test/units/module_utils/facts/system/distribution/fixtures/sles_11.4.json
test/units/module_utils/facts/system/distribution/fixtures/sles_12_sp0.json
test/units/module_utils/facts/system/distribution/fixtures/sles_12_sp1.json
test/units/module_utils/facts/system/distribution/fixtures/smartos_global_zone.json
test/units/module_utils/facts/system/distribution/fixtures/smartos_zone.json
test/units/module_utils/facts/system/distribution/fixtures/smgl_na.json
test/units/module_utils/facts/system/distribution/fixtures/solaris_10.json
test/units/module_utils/facts/system/distribution/fixtures/solaris_11.3.json
test/units/module_utils/facts/system/distribution/fixtures/solaris_11.4.json
test/units/module_utils/facts/system/distribution/fixtures/solaris_11.json
test/units/module_utils/facts/system/distribution/fixtures/steamos_2.0.json
test/units/module_utils/facts/system/distribution/fixtures/tencentos_3_1.json
test/units/module_utils/facts/system/distribution/fixtures/truenas_12.0rc1.json
test/units/module_utils/facts/system/distribution/fixtures/ubuntu_10.04_guess.json
test/units/module_utils/facts/system/distribution/fixtures/ubuntu_12.04.json
test/units/module_utils/facts/system/distribution/fixtures/ubuntu_14.04.json
test/units/module_utils/facts/system/distribution/fixtures/ubuntu_16.04.json
test/units/module_utils/facts/system/distribution/fixtures/ubuntu_18.04.json
test/units/module_utils/facts/system/distribution/fixtures/uos_20.json
test/units/module_utils/facts/system/distribution/fixtures/virtuozzo_7.3.json
test/units/module_utils/facts/virtual/__init__.py
test/units/module_utils/facts/virtual/test_hpux.py
test/units/module_utils/facts/virtual/test_linux.py
test/units/module_utils/facts/virtual/test_sunos.py
test/units/module_utils/facts/virtual/test_sysctl.py
test/units/module_utils/json_utils/__init__.py
test/units/module_utils/json_utils/test_filter_non_json_lines.py
test/units/module_utils/parsing/test_convert_bool.py
test/units/module_utils/urls/__init__.py
test/units/module_utils/urls/test_RedirectHandlerFactory.py
test/units/module_utils/urls/test_Request.py
test/units/module_utils/urls/test_channel_binding.py
test/units/module_utils/urls/test_fetch_file.py
test/units/module_utils/urls/test_fetch_url.py
test/units/module_utils/urls/test_generic_urlparse.py
test/units/module_utils/urls/test_gzip.py
test/units/module_utils/urls/test_prepare_multipart.py
test/units/module_utils/urls/test_split.py
test/units/module_utils/urls/test_urls.py
test/units/module_utils/urls/fixtures/client.key
test/units/module_utils/urls/fixtures/client.pem
test/units/module_utils/urls/fixtures/client.txt
test/units/module_utils/urls/fixtures/multipart.txt
test/units/module_utils/urls/fixtures/netrc
test/units/module_utils/urls/fixtures/cbt/ecdsa_sha256.pem
test/units/module_utils/urls/fixtures/cbt/ecdsa_sha512.pem
test/units/module_utils/urls/fixtures/cbt/rsa-pss_sha256.pem
test/units/module_utils/urls/fixtures/cbt/rsa-pss_sha512.pem
test/units/module_utils/urls/fixtures/cbt/rsa_md5.pem
test/units/module_utils/urls/fixtures/cbt/rsa_sha.pem
test/units/module_utils/urls/fixtures/cbt/rsa_sha1.pem
test/units/module_utils/urls/fixtures/cbt/rsa_sha256.pem
test/units/module_utils/urls/fixtures/cbt/rsa_sha384.pem
test/units/module_utils/urls/fixtures/cbt/rsa_sha512.pem
test/units/modules/__init__.py
test/units/modules/conftest.py
test/units/modules/mount_facts_data.py
test/units/modules/test_apt.py
test/units/modules/test_apt_key.py
test/units/modules/test_async_wrapper.py
test/units/modules/test_copy.py
test/units/modules/test_debconf.py
test/units/modules/test_get_url.py
test/units/modules/test_hostname.py
test/units/modules/test_iptables.py
test/units/modules/test_known_hosts.py
test/units/modules/test_mount_facts.py
test/units/modules/test_pip.py
test/units/modules/test_service.py
test/units/modules/test_service_facts.py
test/units/modules/test_systemd.py
test/units/modules/test_unarchive.py
test/units/modules/test_uri.py
test/units/modules/utils.py
test/units/parsing/__init__.py
test/units/parsing/test_ajson.py
test/units/parsing/test_dataloader.py
test/units/parsing/test_mod_args.py
test/units/parsing/test_splitter.py
test/units/parsing/test_unquote.py
test/units/parsing/fixtures/ajson.json
test/units/parsing/fixtures/vault.yml
test/units/parsing/utils/__init__.py
test/units/parsing/utils/test_addresses.py
test/units/parsing/utils/test_yaml.py
test/units/parsing/vault/__init__.py
test/units/parsing/vault/test_vault.py
test/units/parsing/vault/test_vault_editor.py
test/units/parsing/yaml/__init__.py
test/units/parsing/yaml/test_dumper.py
test/units/parsing/yaml/test_errors.py
test/units/parsing/yaml/test_loader.py
test/units/parsing/yaml/test_objects.py
test/units/parsing/yaml/test_vault.py
test/units/playbook/__init__.py
test/units/playbook/test_attribute.py
test/units/playbook/test_base.py
test/units/playbook/test_block.py
test/units/playbook/test_collectionsearch.py
test/units/playbook/test_helpers.py
test/units/playbook/test_included_file.py
test/units/playbook/test_play.py
test/units/playbook/test_play_context.py
test/units/playbook/test_playbook.py
test/units/playbook/test_taggable.py
test/units/playbook/test_task.py
test/units/playbook/role/__init__.py
test/units/playbook/role/test_include_role.py
test/units/playbook/role/test_role.py
test/units/plugins/__init__.py
test/units/plugins/test_plugins.py
test/units/plugins/action/__init__.py
test/units/plugins/action/test_action.py
test/units/plugins/action/test_gather_facts.py
test/units/plugins/action/test_raw.py
test/units/plugins/action/test_reboot.py
test/units/plugins/become/__init__.py
test/units/plugins/become/conftest.py
test/units/plugins/become/test_su.py
test/units/plugins/become/test_sudo.py
test/units/plugins/cache/__init__.py
test/units/plugins/cache/test_cache.py
test/units/plugins/callback/__init__.py
test/units/plugins/callback/test_callback.py
test/units/plugins/connection/__init__.py
test/units/plugins/connection/test_connection.py
test/units/plugins/connection/test_local.py
test/units/plugins/connection/test_paramiko_ssh.py
test/units/plugins/connection/test_psrp.py
test/units/plugins/connection/test_ssh.py
test/units/plugins/connection/test_winrm.py
test/units/plugins/filter/__init__.py
test/units/plugins/filter/test_core.py
test/units/plugins/filter/test_mathstuff.py
test/units/plugins/inventory/__init__.py
test/units/plugins/inventory/test_constructed.py
test/units/plugins/inventory/test_inventory.py
test/units/plugins/loader_fixtures/__init__.py
test/units/plugins/loader_fixtures/import_fixture.py
test/units/plugins/lookup/__init__.py
test/units/plugins/lookup/test_env.py
test/units/plugins/lookup/test_ini.py
test/units/plugins/lookup/test_password.py
test/units/plugins/lookup/test_url.py
test/units/plugins/shell/__init__.py
test/units/plugins/shell/test_cmd.py
test/units/plugins/shell/test_powershell.py
test/units/plugins/strategy/__init__.py
test/units/plugins/strategy/test_linear.py
test/units/plugins/test/__init__.py
test/units/plugins/test/test_core.py
test/units/regex/test_invalid_var_names.py
test/units/template/__init__.py
test/units/template/test_template.py
test/units/test_utils/__init__.py
test/units/test_utils/controller/__init__.py
test/units/test_utils/controller/display.py
test/units/utils/__init__.py
test/units/utils/conftest.py
test/units/utils/test_cleanup_tmp_file.py
test/units/utils/test_context_objects.py
test/units/utils/test_datatag.py
test/units/utils/test_display.py
test/units/utils/test_encrypt.py
test/units/utils/test_helpers.py
test/units/utils/test_isidentifier.py
test/units/utils/test_json.py
test/units/utils/test_listify.py
test/units/utils/test_plugin_docs.py
test/units/utils/test_serialization.py
test/units/utils/test_serialization_profiles.py
test/units/utils/test_shlex.py
test/units/utils/test_vars.py
test/units/utils/test_version.py
test/units/utils/collection_loader/__init__.py
test/units/utils/collection_loader/test_collection_loader.py
test/units/utils/collection_loader/fixtures/collections/ansible_collections/ansible/builtin/plugins/modules/shouldnotload.py
test/units/utils/collection_loader/fixtures/collections/ansible_collections/testns/testcoll/meta/runtime.yml
test/units/utils/collection_loader/fixtures/collections/ansible_collections/testns/testcoll/plugins/action/my_action.py
test/units/utils/collection_loader/fixtures/collections/ansible_collections/testns/testcoll/plugins/module_utils/__init__.py
test/units/utils/collection_loader/fixtures/collections/ansible_collections/testns/testcoll/plugins/module_utils/my_other_util.py
test/units/utils/collection_loader/fixtures/collections/ansible_collections/testns/testcoll/plugins/module_utils/my_util.py
test/units/utils/collection_loader/fixtures/collections/ansible_collections/testns/testcoll/plugins/modules/__init__.py
test/units/utils/collection_loader/fixtures/collections/ansible_collections/testns/testcoll/plugins/modules/amodule.py
test/units/utils/collection_loader/fixtures/collections/ansible_collections/testns/testcoll/roles/some_role/.gitkeep
test/units/utils/collection_loader/fixtures/collections_masked/ansible_collections/__init__.py
test/units/utils/collection_loader/fixtures/collections_masked/ansible_collections/ansible/__init__.py
test/units/utils/collection_loader/fixtures/collections_masked/ansible_collections/testns/__init__.py
test/units/utils/collection_loader/fixtures/collections_masked/ansible_collections/testns/testcoll/__init__.py
test/units/utils/collection_loader/fixtures/collections_masked/ansible_collections/testns/testcoll2/__init__.py
test/units/utils/collection_loader/fixtures/playbook_path/collections/ansible_collections/ansible/playbook_adj_other/.gitkeep
test/units/utils/collection_loader/fixtures/playbook_path/collections/ansible_collections/freshns/playbook_adj_other/.gitkeep
test/units/utils/collection_loader/fixtures/playbook_path/collections/ansible_collections/testns/playbook_adj_other/.gitkeep
test/units/utils/display/test_broken_cowsay.py
test/units/utils/display/test_curses.py
test/units/utils/display/test_display.py
test/units/utils/display/test_logger.py
test/units/utils/display/test_warning.py
test/units/utils/expected_serialization_profiles/cache_persistence.txt
test/units/utils/expected_serialization_profiles/fallback_to_str.txt
test/units/utils/expected_serialization_profiles/inventory_legacy.txt
test/units/utils/expected_serialization_profiles/legacy.txt
test/units/utils/expected_serialization_profiles/module_legacy_c2m.txt
test/units/utils/expected_serialization_profiles/module_legacy_m2c.txt
test/units/utils/expected_serialization_profiles/module_modern_c2m.txt
test/units/utils/expected_serialization_profiles/module_modern_m2c.txt
test/units/utils/expected_serialization_profiles/tagless.txt
test/units/vars/__init__.py
test/units/vars/test_module_response_deepcopy.py
test/units/vars/test_variable_manager.py ansible_core-2.19.0b4/ansible_core.egg-info/dependency_links.txt 0000644 0000000 0000000 00000000001 15010426755 023406 0 ustar 00root root
ansible_core-2.19.0b4/ansible_core.egg-info/entry_points.txt 0000644 0000000 0000000 00000000703 15010426755 022636 0 ustar 00root root [console_scripts]
ansible = ansible.cli.adhoc:main
ansible-config = ansible.cli.config:main
ansible-console = ansible.cli.console:main
ansible-doc = ansible.cli.doc:main
ansible-galaxy = ansible.cli.galaxy:main
ansible-inventory = ansible.cli.inventory:main
ansible-playbook = ansible.cli.playbook:main
ansible-pull = ansible.cli.pull:main
ansible-test = ansible_test._util.target.cli.ansible_test_cli_stub:main
ansible-vault = ansible.cli.vault:main
ansible_core-2.19.0b4/ansible_core.egg-info/requires.txt 0000644 0000000 0000000 00000000112 15010426755 021732 0 ustar 00root root jinja2>=3.1.0
PyYAML>=5.1
cryptography
packaging
resolvelib<2.0.0,>=0.5.3
ansible_core-2.19.0b4/ansible_core.egg-info/top_level.txt 0000644 0000000 0000000 00000000025 15010426755 022067 0 ustar 00root root ansible
ansible_test
ansible_core-2.19.0b4/changelogs/ 0000755 0000000 0000000 00000000000 15010426755 015333 5 ustar 00root root ansible_core-2.19.0b4/changelogs/CHANGELOG-v2.19.rst 0000644 0000000 0000000 00000136424 15010426755 020143 0 ustar 00root root ==================================================================
ansible-core 2.19 "What Is and What Should Never Be" Release Notes
==================================================================
.. contents:: Topics
v2.19.0b4
=========
Release Summary
---------------
| Release Date: 2025-05-12
| `Porting Guide `__
Minor Changes
-------------
- facts - add "CloudStack KVM Hypervisor" for Linux VM in virtual facts (https://github.com/ansible/ansible/issues/85089).
- modules - use ``AnsibleModule.warn`` instead of passing ``warnings`` to ``exit_json`` or ``fail_json`` which is deprecated.
Bugfixes
--------
- ansible-test - Updated the ``pylint`` sanity test to skip some deprecation validation checks when all arguments are dynamic.
- config - Preserve or apply Origin tag to values returned by config.
- config - Prevented fatal errors when ``MODULE_IGNORE_EXTS`` configuration was set.
- config - Templating failures on config defaults now issue a warning. Previously, failures silently returned an unrendered and untrusted template to the caller.
- config - ``ensure_type`` correctly propagates trust and other tags on returned values.
- config - ``ensure_type`` now converts mappings to ``dict`` when requested, instead of returning the mapping.
- config - ``ensure_type`` now converts sequences to ``list`` when requested, instead of returning the sequence.
- config - ``ensure_type`` now correctly errors when ``pathlist`` or ``pathspec`` types encounter non-string list items.
- config - ``ensure_type`` now reports an error when ``bytes`` are provided for any known ``value_type``. Previously, the behavior was undefined, but often resulted in an unhandled exception or incorrect return type.
- config - ``ensure_type`` with expected type ``int`` now properly converts ``True`` and ``False`` values to ``int``. Previously, these values were silently returned unmodified.
- convert_bool.boolean API conversion function - Unhashable values passed to ``boolean`` behave like other non-boolean convertible values, returning False or raising ``TypeError`` depending on the value of ``strict``. Previously, unhashable values always raised ``ValueError`` due to an invalid set membership check.
- dnf5 - when ``bugfix`` and/or ``security`` is specified, skip packages that do not have any such updates, even for new versions of libdnf5 where this functionality changed and it is considered failure
- plugin loader - Apply template trust to strings loaded from plugin configuration definitions and doc fragments.
- template action - Template files where the entire file's output renders as ``None`` are no longer emitted as the string "None", but instead render to an empty file as in previous releases.
v2.19.0b3
=========
Release Summary
---------------
| Release Date: 2025-05-06
| `Porting Guide `__
Minor Changes
-------------
- ansible-config will now show internal, but not test configuration entries. This allows for debugging but still denoting the configurations as internal use only (_ prefix).
- ansible-test - Improved ``pylint`` checks for Ansible-specific deprecation functions.
- ansible-test - Use the ``-t`` option to set the stop timeout when stopping a container. This avoids use of the ``--time`` option which was deprecated in Docker v28.0.
- collection metadata - The collection loader now parses scalar values from ``meta/runtime.yml`` as strings. This avoids issues caused by unquoted values such as versions or dates being parsed as types other than strings.
- deprecation warnings - Deprecation warning APIs automatically capture the identity of the deprecating plugin. The ``collection_name`` argument is only required to correctly attribute deprecations that occur in module_utils or other non-plugin code.
- deprecation warnings - Improved deprecation messages to more clearly indicate the affected content, including plugin name when available.
- deprecations - Collection name strings not of the form ``ns.coll`` passed to deprecation API functions will result in an error.
- deprecations - Removed support for specifying deprecation dates as a ``datetime.date``, which was included in an earlier 2.19 pre-release.
- deprecations - Some argument names to ``deprecate_value`` for consistency with existing APIs. An earlier 2.19 pre-release included a ``removal_`` prefix on the ``date`` and ``version`` arguments.
- modules - The ``AnsibleModule.deprecate`` function no longer sends deprecation messages to the target host's logging system.
Deprecated Features
-------------------
- Passing a ``warnings` or ``deprecations`` key to ``exit_json`` or ``fail_json`` is deprecated. Use ``AnsibleModule.warn`` or ``AnsibleModule.deprecate`` instead.
- plugins - Accessing plugins with ``_``-prefixed filenames without the ``_`` prefix is deprecated.
Bugfixes
--------
- Ansible will now ensure predictable permissions on remote artifacts, until now it only ensured executable and relied on system masks for the rest.
- dnf5 - avoid generating excessive transaction entries in the dnf5 history (https://github.com/ansible/ansible/issues/85046)
v2.19.0b2
=========
Release Summary
---------------
| Release Date: 2025-04-24
| `Porting Guide `__
Minor Changes
-------------
- comment filter - Improve the error message shown when an invalid ``style`` argument is provided.
Bugfixes
--------
- Remove use of `required` parameter in `get_bin_path` which has been deprecated.
- ansible-doc - fix indentation for first line of descriptions of suboptions and sub-return values (https://github.com/ansible/ansible/pull/84690).
- ansible-doc - fix line wrapping for first line of description of options and return values (https://github.com/ansible/ansible/pull/84690).
v2.19.0b1
=========
Release Summary
---------------
| Release Date: 2025-04-14
| `Porting Guide `__
Major Changes
-------------
- Jinja plugins - Jinja builtin filter and test plugins are now accessible via their fully-qualified names ``ansible.builtin.{name}``.
- Task Execution / Forks - Forks no longer inherit stdio from the parent ``ansible-playbook`` process. ``stdout``, ``stderr``, and ``stdin`` within a worker are detached from the terminal, and non-functional. All needs to access stdio from a fork for controller side plugins requires use of ``Display``.
- ansible-test - Packages beneath ``module_utils`` can now contain ``__init__.py`` files.
- variables - The type system underlying Ansible's variable storage has been significantly overhauled and formalized. Attempts to store unsupported Python object types in variables will now result in an error.
- variables - To support new Ansible features, many variable objects are now represented by subclasses of their respective native Python types. In most cases, they behave indistinguishably from their original types, but some Python libraries do not handle builtin object subclasses properly. Custom plugins that interact with such libraries may require changes to convert and pass the native types.
Minor Changes
-------------
- Added a -vvvvv log message indicating when a host fails to produce output within the timeout period.
- AnsibleModule.uri - Add option ``multipart_encoding`` for ``form-multipart`` files in body to change default base64 encoding for files
- INVENTORY_IGNORE_EXTS config, removed ``ini`` from the default list, inventory scripts using a corresponding .ini configuration are rare now and inventory.ini files are more common. Those that need to ignore the ini files for inventory scripts can still add it to configuration.
- Jinja plugins - Plugins can declare support for undefined values.
- Jinja2 version 3.1.0 or later is now required on the controller.
- Move ``follow_redirects`` parameter to module_utils so external modules can reuse it.
- PlayIterator - do not return tasks from already executed roles so specific strategy plugins do not have to do the filtering of such tasks themselves
- SSH Escalation-related -vvv log messages now include the associated host information.
- Windows - Add support for Windows Server 2025 to Ansible and as an ``ansible-test`` remote target - https://github.com/ansible/ansible/issues/84229
- Windows - refactor the async implementation to better handle errors during bootstrapping and avoid WMI when possible.
- ``ansible-galaxy collection install`` — the collection dependency resolver now prints out conflicts it hits during dependency resolution when it's taking too long and it ends up backtracking a lot. It also displays suggestions on how to help it compute the result more quickly.
- ansible, ansible-console, ansible-pull - add --flush-cache option (https://github.com/ansible/ansible/issues/83749).
- ansible-galaxy - Add support for Keycloak service accounts
- ansible-galaxy - support ``resolvelib >= 0.5.3, < 2.0.0`` (https://github.com/ansible/ansible/issues/84217).
- ansible-test - Added a macOS 15.3 remote VM, replacing 14.3.
- ansible-test - Automatically retry HTTP GET/PUT/DELETE requests on exceptions.
- ansible-test - Default to Python 3.13 in the ``base`` and ``default`` containers.
- ansible-test - Disable the ``deprecated-`` prefixed ``pylint`` rules as their results vary by Python version.
- ansible-test - Disable the ``pep8`` sanity test rules ``E701`` and ``E704`` to improve compatibility with ``black``.
- ansible-test - Improve container runtime probe error handling. When unexpected probe output is encountered, an error with more useful debugging information is provided.
- ansible-test - Replace container Alpine 3.20 with 3.21.
- ansible-test - Replace container Fedora 40 with 41.
- ansible-test - Replace remote Alpine 3.20 with 3.21.
- ansible-test - Replace remote Fedora 40 with 41.
- ansible-test - Replace remote FreeBSD 13.3 with 13.5.
- ansible-test - Replace remote FreeBSD 14.1 with 14.2.
- ansible-test - Replace remote RHEL 9.4 with 9.5.
- ansible-test - Show a more user-friendly error message when a ``runme.sh`` script is not executable.
- ansible-test - The ``yamllint`` sanity test now enforces string values for the ``!vault`` tag.
- ansible-test - Update ``nios-test-container`` to version 7.0.0.
- ansible-test - Update ``pylint`` sanity test to use version 3.3.1.
- ansible-test - Update distro containers to remove unnecessary pakages (apache2, subversion, ruby).
- ansible-test - Update sanity test requirements to latest available versions.
- ansible-test - Update the HTTP test container.
- ansible-test - Update the PyPI test container.
- ansible-test - Update the ``base`` and ``default`` containers.
- ansible-test - Update the utility container.
- ansible-test - Use Python's ``urllib`` instead of ``curl`` for HTTP requests.
- ansible-test - When detection of the current container network fails, a warning is now issued and execution continues. This simplifies usage in cases where the current container cannot be inspected, such as when running in GitHub Codespaces.
- ansible-test acme test container - bump `version to 2.3.0 `__ to include newer versions of Pebble, dependencies, and runtimes. This adds support for ACME profiles, ``dns-account-01`` support, and some smaller improvements (https://github.com/ansible/ansible/pull/84547).
- apt_key module - add notes to docs and errors to point at the CLI tool deprecation by Debian and alternatives
- apt_repository module - add notes to errors to point at the CLI tool deprecation by Debian and alternatives
- become plugins get new property 'pipelining' to show support or lack there of for the feature.
- callback plugins - add has_option() to CallbackBase to match other functions overloaded from AnsiblePlugin
- callback plugins - fix get_options() for CallbackBase
- copy - fix sanity test failures (https://github.com/ansible/ansible/pull/83643).
- copy - parameter ``local_follow`` was incorrectly documented as having default value ``True`` (https://github.com/ansible/ansible/pull/83643).
- cron - Provide additional error information while writing cron file (https://github.com/ansible/ansible/issues/83223).
- csvfile - let the config system do the typecasting (https://github.com/ansible/ansible/pull/82263).
- display - Deduplication of warning and error messages considers the full content of the message (including source and traceback contexts, if enabled). This may result in fewer messages being omitted.
- distribution - Added openSUSE MicroOS to Suse OS family (#84685).
- dnf5, apt - add ``auto_install_module_deps`` option (https://github.com/ansible/ansible/issues/84206)
- docs - add collection name in message from which the module is being deprecated (https://github.com/ansible/ansible/issues/84116).
- env lookup - The error message generated for a missing environment variable when ``default`` is an undefined value (e.g. ``undef('something')``) will contain the hint from that undefined value, except when the undefined value is the default of ``undef()`` with no arguments. Previously, any existing undefined hint would be ignored.
- file - enable file module to disable diff_mode (https://github.com/ansible/ansible/issues/80817).
- file - make code more readable and simple.
- filter - add support for URL-safe encoding and decoding in b64encode and b64decode (https://github.com/ansible/ansible/issues/84147).
- find - add a checksum_algorithm parameter to specify which type of checksum the module will return
- from_json filter - The filter accepts a ``profile`` argument, which defaults to ``tagless``.
- handlers - Templated handler names with syntax errors, or that resolve to ``omit`` are now skipped like handlers with undefined variables in their name.
- improved error message for yaml parsing errors in plugin documentation
- local connection plugin - A new ``become_strip_preamble`` config option (default True) was added; disable to preserve diagnostic ``become`` output in task results.
- local connection plugin - A new ``become_success_timeout`` operation-wide timeout config (default 10s) was added for ``become``.
- local connection plugin - When a ``become`` plugin's ``prompt`` value is a non-string after the ``check_password_prompt`` callback has completed, no prompt stripping will occur on stderr.
- lookup_template - add an option to trim blocks while templating (https://github.com/ansible/ansible/issues/75962).
- module - set ipv4 and ipv6 rules simultaneously in iptables module (https://github.com/ansible/ansible/issues/84404).
- module_utils - Add ``NoReturn`` type annotations to functions which never return.
- modules - PowerShell modules can now receive ``datetime.date``, ``datetime.time`` and ``datetime.datetime`` values as ISO 8601 strings.
- modules - PowerShell modules can now receive strings sourced from inline vault-encrypted strings.
- modules - Unhandled exceptions during Python module execution are now returned as structured data from the target. This allows the new traceback handling to be applied to exceptions raised on targets.
- pipelining logic has mostly moved to connection plugins so they can decide/override settings.
- plugin error handling - When raising exceptions in an exception handler, be sure to use ``raise ... from`` as appropriate. This supersedes the use of the ``AnsibleError`` arg ``orig_exc`` to represent the cause. Specifying ``orig_exc`` as the cause is still permitted. Failure to use ``raise ... from`` when ``orig_exc`` is set will result in a warning. Additionally, if the two cause exceptions do not match, a warning will be issued.
- removed harcoding of su plugin as it now works with pipelining.
- runtime-metadata sanity test - improve validation of ``action_groups`` (https://github.com/ansible/ansible/pull/83965).
- service_facts module got freebsd support added.
- ssh connection plugin - Support ``SSH_ASKPASS`` mechanism to provide passwords, making it the default, but still offering an explicit choice to use ``sshpass`` (https://github.com/ansible/ansible/pull/83936)
- ssh connection plugin now overrides pipelining when a tty is requested.
- ssh-agent - ``ansible``, ``ansible-playbook`` and ``ansible-console`` are capable of spawning or reusing an ssh-agent, allowing plugins to interact with the ssh-agent. Additionally a pure python ssh-agent client has been added, enabling easy interaction with the agent. The ssh connection plugin contains new functionality via ``ansible_ssh_private_key`` and ``ansible_ssh_private_key_passphrase``, for loading an SSH private key into the agent from a variable.
- templating - Access to an undefined variable from inside a lookup, filter, or test (which raises MarkerError) no longer ends processing of the current template. The triggering undefined value is returned as the result of the offending plugin invocation, and the template continues to execute.
- templating - Embedding ``range()`` values in containers such as lists will result in an error on use. Previously the value would be converted to a string representing the range parameters, such as ``range(0, 3)``.
- templating - Handling of omitted values is now a first-class feature of the template engine, and is usable in all Ansible Jinja template contexts. Any template that resolves to ``omit`` is automatically removed from its parent container during templating.
- templating - Template evaluation is lazier than in previous versions. Template expressions which resolve only portions of a data structure no longer result in the entire structure being templated.
- templating - Templating errors now provide more information about both the location and context of the error, especially for deeply-nested and/or indirected templating scenarios.
- templating - Unified ``omit`` behavior now requires that plugins calling ``Templar.template()`` handle cases where the entire template result is omitted, by catching the ``AnsibleValueOmittedError`` that is raised. Previously, this condition caused a randomly-generated string marker to appear in the template result.
- templating - Variables of type ``set`` and ``tuple`` are now converted to ``list`` when exiting the final pass of templating.
- to_json / to_nice_json filters - The filters accept a ``profile`` argument, which defaults to ``tagless``.
- troubleshooting - Tracebacks can be collected and displayed for most errors, warnings, and deprecation warnings (including those generated by modules). Tracebacks are no longer enabled with ``-vvv``; the behavior is directly configurable via the ``DISPLAY_TRACEBACK`` config option. Module tracebacks passed to ``fail_json`` via the ``exception`` kwarg will not be included in the task result unless error tracebacks are configured.
- undef jinja function - The ``undef`` jinja function now raises an error if a non-string hint is given. Attempting to use an undefined hint also results in an error, ensuring incorrect use of the function can be distinguished from the function's normal behavior.
- validate-modules sanity test - make sure that ``module`` and ``plugin`` ``seealso`` entries use FQCNs (https://github.com/ansible/ansible/pull/84325).
- vault - improved vault filter documentation by adding missing example content for dump_template_data.j2, refining examples for clarity, and ensuring variable consistency (https://github.com/ansible/ansible/issues/83583).
- warnings - All warnings (including deprecation warnings) issued during a task's execution are now accessible via the ``warnings`` and ``deprecations`` keys on the task result.
- when the ``dict`` lookup is given a non-dict argument, show the value of the argument and its type in the error message.
- windows - add hard minimum limit for PowerShell to 5.1. Ansible dropped support for older versions of PowerShell in the 2.16 release but this reqirement is now enforced at runtime.
- windows - refactor windows exec runner to improve efficiency and add better error reporting on failures.
- winrm - Remove need for pexpect on macOS hosts when using ``kinit`` to retrieve the Kerberos TGT. By default the code will now only use the builtin ``subprocess`` library which should handle issues with select and a high fd count and also simplify the code.
Breaking Changes / Porting Guide
--------------------------------
- Support for the ``toml`` library has been removed from TOML inventory parsing and dumping. Use ``tomli`` for parsing on Python 3.10. Python 3.11 and later have built-in support for parsing. Use ``tomli-w`` to support outputting inventory in TOML format.
- assert - The ``quiet`` argument must be a commonly-accepted boolean value. Previously, unrecognized values were silently treated as False.
- callback plugins - The structure of the ``exception``, ``warnings`` and ``deprecations`` values visible to callbacks has changed. Callbacks that inspect or serialize these values may require special handling.
- conditionals - Conditional expressions that result in non-boolean values are now an error by default. Such results often indicate unintentional use of templates where they are not supported, resulting in a conditional that is always true. When this option is enabled, conditional expressions which are a literal ``None`` or empty string will evaluate as true, for backwards compatibility. The error can be temporarily changed to a deprecation warning by enabling the ``ALLOW_BROKEN_CONDITIONALS`` config option.
- first_found lookup - When specifying ``files`` or ``paths`` as a templated list containing undefined values, the undefined list elements will be discarded with a warning. Previously, the entire list would be discarded without any warning.
- internals - The ``AnsibleLoader`` and ``AnsibleDumper`` classes for working with YAML are now factory functions and cannot be extended.
- internals - The ``ansible.utils.native_jinja`` Python module has been removed.
- inventory - Invalid variable names provided by inventories result in an inventory parse failure. This behavior is now consistent with other variable name usages throughout Ansible.
- lookup plugins - Lookup plugins called as `with_(lookup)` will no longer have the `_subdir` attribute set.
- lookup plugins - ``terms`` will always be passed to ``run`` as the first positional arg, where previously it was sometimes passed as a keyword arg when using ``with_`` syntax.
- loops - Omit placeholders no longer leak between loop item templating and task templating. Previously, ``omit`` placeholders could remain embedded in loop items after templating and be used as an ``omit`` for task templating. Now, values resolving to ``omit`` are dropped immediately when loop items are templated. To turn missing values into an ``omit`` for task templating, use ``| default(omit)``. This solution is backwards compatible with previous versions of ansible-core.
- modules - Ansible modules using ``sys.excepthook`` must use a standard ``try/except`` instead.
- plugins - Any plugin that sources or creates templates must properly tag them as trusted.
- plugins - Custom Jinja plugins that accept undefined top-level arguments must opt in to receiving them.
- plugins - Custom Jinja plugins that use ``environment.getitem`` to retrieve undefined values will now trigger a ``MarkerError`` exception. This exception must be handled to allow the plugin to return a ``Marker``, or the plugin must opt-in to accepting ``Marker`` values.
- public API - The ``ansible.vars.fact_cache.FactCache`` wrapper has been removed.
- serialization of ``omit`` sentinel - Serialization of variables containing ``omit`` sentinels (e.g., by the ``to_json`` and ``to_yaml`` filters or ``ansible-inventory``) will fail if the variable has not completed templating. Previously, serialization succeeded with placeholder strings emitted in the serialized output.
- set_fact - The string values "yes", "no", "true" and "false" were previously converted (ignoring case) to boolean values when not using Jinja2 native mode. Since Jinja2 native mode is always used, this conversion no longer occurs. When boolean values are required, native boolean syntax should be used where variables are defined, such as in YAML. When native boolean syntax is not an option, the ``bool`` filter can be used to parse string values into booleans.
- template lookup - The ``convert_data`` option is deprecated and no longer has any effect. Use the ``from_json`` filter on the lookup result instead.
- templating - Access to ``_`` prefixed attributes and methods, and methods with known side effects, is no longer permitted. In cases where a matching mapping key is present, the associated value will be returned instead of an error. This increases template environment isolation and ensures more consistent behavior between the ``.`` and ``[]`` operators.
- templating - Conditionals and lookups which use embedded inline templates in Jinja string constants now display a warning. These templates should be converted to their expression equivalent.
- templating - Many Jinja plugins (filters, lookups, tests) and methods previously silently ignored undefined inputs, which often masked subtle errors. Passing an undefined argument to a Jinja plugin or method that does not declare undefined support now results in an undefined value.
- templating - Templates are always rendered in Jinja2 native mode. As a result, non-string values are no longer automatically converted to strings.
- templating - Templates resulting in ``None`` are no longer automatically converted to an empty string.
- templating - Templates with embedded inline templates that were not contained within a Jinja string constant now result in an error, as support for multi-pass templating was removed for security reasons. In most cases, such templates can be easily rewritten to avoid the use of embedded inline templates.
- templating - The ``allow_unsafe_lookups`` option no longer has any effect. Lookup plugins are responsible for tagging strings containing templates to allow evaluation as a template.
- templating - The result of the ``range()`` global function cannot be returned from a template- it should always be passed to a filter (e.g., ``random``). Previously, range objects returned from an intermediate template were always converted to a list, which is inconsistent with inline consumption of range objects.
- templating - ``#jinja2:`` overrides in templates with invalid override names or types are now templating errors.
Deprecated Features
-------------------
- CLI - The ``--inventory-file`` option alias is deprecated. Use the ``-i`` or ``--inventory`` option instead.
- Stategy Plugins - Use of strategy plugins not provided in ``ansible.builtin`` are deprecated and do not carry any backwards compatibility guarantees going forward. A future release will remove the ability to use external strategy plugins. No alternative for third party strategy plugins is currently planned.
- ``ansible.module_utils.compat.datetime`` - The datetime compatibility shims are now deprecated. They are scheduled to be removed in ``ansible-core`` v2.21. This includes ``UTC``, ``utcfromtimestamp()`` and ``utcnow`` importable from said module (https://github.com/ansible/ansible/pull/81874).
- bool filter - Support for coercing unrecognized input values (including None) has been deprecated. Consult the filter documentation for acceptable values, or consider use of the ``truthy`` and ``falsy`` tests.
- cache plugins - The `ansible.plugins.cache.base` Python module is deprecated. Use `ansible.plugins.cache` instead.
- callback plugins - The `v2_on_any` callback method is deprecated. Use specific callback methods instead.
- callback plugins - The v1 callback API (callback methods not prefixed with `v2_`) is deprecated. Use `v2_` prefixed methods instead.
- conditionals - Conditionals using Jinja templating delimiters (e.g., ``{{``, ``{%``) should be rewritten as expressions without delimiters, unless the entire conditional value is a single template that resolves to a trusted string expression. This is useful for dynamic indirection of conditional expressions, but is limited to trusted literal string expressions.
- config - The ``ACTION_WARNINGS`` config has no effect. It previously disabled command warnings, which have since been removed.
- config - The ``DEFAULT_JINJA2_NATIVE`` option has no effect. Jinja2 native mode is now the default and only option.
- config - The ``DEFAULT_NULL_REPRESENTATION`` option has no effect. Null values are no longer automatically converted to another value during templating of single variable references.
- display - The ``Display.get_deprecation_message`` method has been deprecated. Call ``Display.deprecated`` to display a deprecation message, or call it with ``removed=True`` to raise an ``AnsibleError``.
- file loading - Loading text files with ``DataLoader`` containing data that cannot be decoded under the expected encoding is deprecated. In most cases the encoding must be UTF-8, although some plugins allow choosing a different encoding. Previously, invalid data was silently wrapped in Unicode surrogate escape sequences, often resulting in later errors or other data corruption.
- first_found lookup - Splitting of file paths on ``,;:`` is deprecated. Pass a list of paths instead. The ``split`` method on strings can be used to split variables into a list as needed.
- interpreter discovery - The ``auto_legacy`` and ``auto_legacy_silent`` options for ``INTERPRETER_PYTHON`` are deprecated. Use ``auto`` or ``auto_silent`` options instead, as they have the same effect.
- oneline callback - The ``oneline`` callback and its associated ad-hoc CLI args (``-o``, ``--one-line``) are deprecated.
- paramiko - The paramiko connection plugin has been deprecated with planned removal in 2.21.
- playbook variables - The ``play_hosts`` variable has been deprecated, use ``ansible_play_batch`` instead.
- plugin error handling - The ``AnsibleError`` constructor arg ``suppress_extended_error`` is deprecated. Using ``suppress_extended_error=True`` has the same effect as ``show_content=False``.
- plugins - The ``listify_lookup_plugin_terms`` function is obsolete and in most cases no longer needed.
- template lookup - The jinja2_native option is no longer used in the Ansible Core code base. Jinja2 native mode is now the default and only option.
- templating - Support for enabling Jinja2 extensions (not plugins) has been deprecated.
- templating - The ``ansible_managed`` variable available for certain templating scenarios, such as the ``template`` action and ``template`` lookup has been deprecated. Define and use a custom variable instead of relying on ``ansible_managed``.
- templating - The ``disable_lookups`` option has no effect, since plugins must be updated to apply trust before any templating can be performed.
- to_yaml/to_nice_yaml filters - Implicit YAML dumping of vaulted value ciphertext is deprecated. Set `dump_vault_tags` to explicitly specify the desired behavior.
- tree callback - The ``tree`` callback and its associated ad-hoc CLI args (``-t``, ``--tree``) are deprecated.
Removed Features (previously deprecated)
----------------------------------------
- Remove deprecated plural form of collection path (https://github.com/ansible/ansible/pull/84156).
- Removed deprecated STRING_CONVERSION_ACTION (https://github.com/ansible/ansible/issues/84220).
- encrypt - passing unsupported passlib hashtype now raises AnsibleFilterError.
- manager - remove deprecated include_delegate_to parameter from get_vars API.
- modules - Modules returning non-UTF8 strings now result in an error. The ``MODULE_STRICT_UTF8_RESPONSE`` setting can be used to disable this check.
- removed deprecated pycompat24 and compat.importlib.
- selector - remove deprecated compat.selector related files (https://github.com/ansible/ansible/pull/84155).
- windows - removed common module functions ``ConvertFrom-AnsibleJson``, ``Format-AnsibleException`` from Windows modules as they are not used and add uneeded complexity to the code.
Security Fixes
--------------
- include_vars action - Ensure that result masking is correctly requested when vault-encrypted files are read. (CVE-2024-8775)
- task result processing - Ensure that action-sourced result masking (``_ansible_no_log=True``) is preserved. (CVE-2024-8775)
- templating - Ansible's template engine no longer processes Jinja templates in strings unless they are marked as coming from a trusted source. Untrusted strings containing Jinja template markers are ignored with a warning. Examples of trusted sources include playbooks, vars files, and many inventory sources. Examples of untrusted sources include module results and facts. Plugins which have not been updated to preserve trust while manipulating strings may inadvertently cause them to lose their trusted status.
- templating - Changes to conditional expression handling removed numerous instances of insecure multi-pass templating (which could result in execution of untrusted template expressions).
- user action won't allow ssh-keygen, chown and chmod to run on existing ssh public key file, avoiding traversal on existing symlinks (CVE-2024-9902).
Bugfixes
--------
- Ansible will now also warn when reserved keywords are set via a module (set_fact, include_vars, etc).
- Ansible.Basic - Fix ``required_if`` check when the option value to check is unset or set to null.
- Correctly return ``False`` when using the ``filter`` and ``test`` Jinja tests on plugin names which are not filters or tests, respectively. (resolves issue https://github.com/ansible/ansible/issues/82084)
- Do not run implicit ``flush_handlers`` meta tasks when the whole play is excluded from the run due to tags specified.
- Errors now preserve stacked error messages even when YAML is involved.
- Fix a display.debug statement with the wrong param in _get_diff_data() method
- Fix disabling SSL verification when installing collections and roles from git repositories. If ``--ignore-certs`` isn't provided, the value for the ``GALAXY_IGNORE_CERTS`` configuration option will be used (https://github.com/ansible/ansible/issues/83326).
- Fix ipv6 pattern bug in lib/ansible/parsing/utils/addresses.py (https://github.com/ansible/ansible/issues/84237)
- Fix returning 'unreachable' for the overall task result. This prevents false positives when a looped task has unignored unreachable items (https://github.com/ansible/ansible/issues/84019).
- Implicit ``meta: flush_handlers`` tasks now have a parent block to prevent potential tracebacks when calling methods like ``get_play()`` on them internally.
- Improve performance on large inventories by reducing the number of implicit meta tasks.
- Jinja plugins - Errors raised will always be derived from ``AnsibleTemplatePluginError``.
- Optimize the way tasks from within ``include_tasks``/``include_role`` are inserted into the play.
- Time out waiting on become is an unreachable error (https://github.com/ansible/ansible/issues/84468)
- Use consistent multiprocessing context for action write locks
- Use the requested error message in the ansible.module_utils.facts.timeout timeout function instead of hardcoding one.
- Windows - add support for running on system where WDAC is in audit mode with ``Dynamic Code Security`` enabled.
- YAML parsing - The `!unsafe` tag no longer coerces non-string scalars to strings.
- ``ansible-galaxy`` — the collection dependency resolver now treats version specifiers starting with ``!=`` as unpinned.
- ``package``/``dnf`` action plugins - provide the reason behind the failure to gather the ``ansible_pkg_mgr`` fact to identify the package backend
- action plugins - Action plugins that raise unhandled exceptions no longer terminate playbook loops. Previously, exceptions raised by an action plugin caused abnormal loop termination and loss of loop iteration results.
- ansible-config - format galaxy server configs while dumping in JSON format (https://github.com/ansible/ansible/issues/84840).
- ansible-doc - If none of the files in files exists, path will be undefined and a direct reference will throw an UnboundLocalError (https://github.com/ansible/ansible/pull/84464).
- ansible-galaxy - Small adjustments to URL building for ``download_url`` and relative redirects.
- ansible-pull change detection will now work independently of callback or result format settings.
- ansible-test - Enable the ``sys.unraisablehook`` work-around for the ``pylint`` sanity test on Python 3.11. Previously the work-around was only enabled for Python 3.12 and later. However, the same issue has been discovered on Python 3.11.
- ansible-test - Ensure CA certificates are installed on managed FreeBSD instances.
- ansible-test - Fix support for PowerShell module_util imports with the ``-Optional`` flag.
- ansible-test - Fix support for detecting PowerShell modules importing module utils with the newer ``#AnsibleRequires`` format.
- ansible-test - Fix traceback that occurs after an interactive command fails.
- ansible-test - Fix up coverage reporting to properly translate the temporary path of integration test modules to the expected static test module path.
- ansible-test - Fixed traceback when handling certain YAML errors in the ``yamllint`` sanity test.
- ansible-test - Managed macOS instances now use the ``sudo_chdir`` option for the ``sudo`` become plugin to avoid permission errors when dropping privileges.
- ansible-vault will now correctly handle `--prompt`, previously it would issue an error about stdin if no 2nd argument was passed
- ansible_uptime_second - added ansible_uptime_seconds fact support for AIX (https://github.com/ansible/ansible/pull/84321).
- apt_key module - prevent tests from running when apt-key was removed
- base.yml - deprecated libvirt_lxc_noseclabel config.
- build - Pin ``wheel`` in ``pyproject.toml`` to ensure compatibility with supported ``setuptools`` versions.
- config - various fixes to config lookup plugin (https://github.com/ansible/ansible/pull/84398).
- copy - refactor copy module for simplicity.
- copy action now prevents user from setting internal options.
- debconf - set empty password values (https://github.com/ansible/ansible/issues/83214).
- debug - hide loop vars in debug var display (https://github.com/ansible/ansible/issues/65856).
- default callback - Error context is now shown for failing tasks that use the ``debug`` action.
- display - The ``Display.deprecated`` method once again properly handles the ``removed=True`` argument (https://github.com/ansible/ansible/issues/82358).
- distro - add support for Linux Mint Debian Edition (LMDE) (https://github.com/ansible/ansible/issues/84934).
- distro - detect Debian as os_family for LMDE 6 (https://github.com/ansible/ansible/issues/84934).
- dnf5 - Handle forwarded exceptions from dnf5-5.2.13 where a generic ``RuntimeError`` was previously raised
- dnf5 - fix ``is_installed`` check for packages that are not installed but listed as provided by an installed package (https://github.com/ansible/ansible/issues/84578)
- dnf5 - fix installing a package using ``state=latest`` when a binary of the same name as the package is already installed (https://github.com/ansible/ansible/issues/84259)
- dnf5 - fix traceback when ``enable_plugins``/``disable_plugins`` is used on ``python3-libdnf5`` versions that do not support this functionality
- dnf5 - libdnf5 - use ``conf.pkg_gpgcheck`` instead of deprecated ``conf.gpgcheck`` which is used only as a fallback
- dnf5 - matching on a binary can be achieved only by specifying a full path (https://github.com/ansible/ansible/issues/84334)
- facts - gather pagesize and calculate respective values depending upon architecture (https://github.com/ansible/ansible/issues/84773).
- facts - skip if distribution file path is directory, instead of raising error (https://github.com/ansible/ansible/issues/84006).
- find - skip ENOENT error code while recursively enumerating files. find module will now be tolerant to race conditions that remove files or directories from the target it is currently inspecting. (https://github.com/ansible/ansible/issues/84873).
- first_found lookup - Corrected return value documentation to reflect None (not empty string) for no files found.
- gather_facts action now defaults to `ansible.legacy.setup` if `smart` was set, no network OS was found and no other alias for `setup` was present.
- gather_facts action will now issues errors and warnings as appropriate if a network OS is detected but no facts modules are defined for it.
- gather_facts action, will now add setup when 'smart' appears with other modules in the FACTS_MODULES setting (#84750).
- get_url - add support for BSD-style checksum digest file (https://github.com/ansible/ansible/issues/84476).
- get_url - fix honoring ``filename`` from the ``content-disposition`` header even when the type is ``inline`` (https://github.com/ansible/ansible/issues/83690)
- host_group_vars - fixed defining the 'key' variable if the get_vars method is called with cache=False (https://github.com/ansible/ansible/issues/84384)
- include_vars - fix including previously undefined hash variables with hash_behaviour merge (https://github.com/ansible/ansible/issues/84295).
- iptables - Allows the wait parameter to be used with iptables chain creation (https://github.com/ansible/ansible/issues/84490)
- linear strategy - fix executing ``end_role`` meta tasks for each host, instead of handling these as implicit run_once tasks (https://github.com/ansible/ansible/issues/84660).
- local connection plugin - Become timeout errors now include all received data. Previously, the most recently-received data was discarded.
- local connection plugin - Ensure ``become`` success validation always occurs, even when an active plugin does not set ``prompt``.
- local connection plugin - Fixed cases where the internal ``BECOME-SUCCESS`` message appeared in task output.
- local connection plugin - Fixed hang or spurious failure when data arrived concurrently on stdout and stderr during a successful ``become`` operation validation.
- local connection plugin - Fixed hang when a become plugin expects a prompt but a password was not provided.
- local connection plugin - Fixed hang when an active become plugin incorrectly signals lack of prompt.
- local connection plugin - Fixed hang when an internal become read timeout expired before the password prompt was written.
- local connection plugin - Fixed hang when only one of stdout or stderr was closed by the ``become_exe`` subprocess.
- local connection plugin - Fixed long timeout/hang for ``become`` plugins that repeat their prompt on failure (e.g., ``sudo``, some ``su`` implementations).
- local connection plugin - Fixed silent ignore of ``become`` failures and loss of task output when data arrived concurrently on stdout and stderr during ``become`` operation validation.
- local connection plugin - Fixed task output header truncation when post-become data arrived before ``become`` operation validation had completed.
- lookup plugins - The ``terms`` arg to the ``run`` method is now always a list. Previously, there were cases where a non-list could be received.
- module arg templating - When using a templated raw task arg and a templated ``args`` keyword, args are now merged. Previously use of templated raw task args silently ignored all values from the templated ``args`` keyword.
- module defaults - Module defaults are no longer templated unless they are used by a task that does not override them. Previously, all module defaults for all modules were templated for every task.
- module respawn - limit to supported Python versions
- omitting task args - Use of omit for task args now properly falls back to args of lower precedence, such as module defaults. Previously an omitted value would obliterate values of lower precedence.
- package_facts module when using 'auto' will return the first package manager found that provides an output, instead of just the first one, as this can be foreign and not have any packages.
- psrp - Improve stderr parsing when running raw commands that emit error records or stderr lines.
- regex_search filter - Corrected return value documentation to reflect None (not empty string) for no match.
- respawn - use copy of env variables to update existing PYTHONPATH value (https://github.com/ansible/ansible/issues/84954).
- runas become - Fix up become logic to still get the SYSTEM token with the most privileges when running as SYSTEM.
- sequence lookup - sequence query/lookups without positional arguments now return a valid list if their kwargs comprise a valid sequence expression (https://github.com/ansible/ansible/issues/82921).
- service_facts - skip lines which does not contain service names in openrc output (https://github.com/ansible/ansible/issues/84512).
- ssh - Improve the logic for parsing CLIXML data in stderr when working with Windows host. This fixes issues when the raw stderr contains invalid UTF-8 byte sequences and improves embedded CLIXML sequences.
- ssh - Raise exception when sshpass returns error code (https://github.com/ansible/ansible/issues/58133).
- ssh - connection options were incorrectly templated during ``reset_connection`` tasks (https://github.com/ansible/ansible/pull/84238).
- stability - Fixed silent process failure on unhandled IOError/OSError under ``linear`` strategy.
- su become plugin - Ensure generated regex from ``prompt_l10n`` config values is properly escaped.
- su become plugin - Ensure that password prompts are correctly detected in the presence of leading output. Previously, this case resulted in a timeout or hang.
- su become plugin - Ensure that trailing colon is expected on all ``prompt_l10n`` config values.
- sudo become plugin - The `sudo_chdir` config option allows the current directory to be set to the specified value before executing sudo to avoid permission errors when dropping privileges.
- sunos - remove hard coding of virtinfo command in facts gathering code (https://github.com/ansible/ansible/pull/84357).
- to_yaml/to_nice_yaml filters - Eliminated possibility of keyword arg collisions with internally-set defaults.
- unarchive - Clamp timestamps from beyond y2038 to representible values when unpacking zip files on platforms that use 32-bit time_t (e.g. Debian i386).
- uri - Form location correctly when the server returns a relative redirect (https://github.com/ansible/ansible/issues/84540)
- uri - Handle HTTP exceptions raised while reading the content (https://github.com/ansible/ansible/issues/83794).
- uri - mark ``url`` as required (https://github.com/ansible/ansible/pull/83642).
- user - Create Buildroot subclass as alias to Busybox (https://github.com/ansible/ansible/issues/83665).
- user - Set timeout for passphrase interaction.
- user - Update prompt for SSH key passphrase (https://github.com/ansible/ansible/issues/84484).
- user - Use higher precedence HOME_MODE as UMASK for path provided (https://github.com/ansible/ansible/pull/84482).
- user action will now require O(force) to overwrite the public part of an ssh key when generating ssh keys, as was already the case for the private part.
- user module now avoids changing ownership of files symlinked in provided home dir skeleton
- vars lookup - The ``default`` substitution only applies when trying to look up a variable which is not defined. If the variable is defined, but templates to an undefined value, the ``default`` substitution will not apply. Use the ``default`` filter to coerce those values instead.
- wait_for_connection - a warning was displayed if any hosts used a local connection (https://github.com/ansible/ansible/issues/84419)
Known Issues
------------
- templating - Any string value starting with ``#jinja2:`` which is templated will always be interpreted as Jinja2 configuration overrides. To include this literal value at the start of a string, a space or other character must precede it.
- variables - Tagged values cannot be used for dictionary keys in many circumstances.
- variables - The values ``None``, ``True`` and ``False`` cannot be tagged because they are singletons. Attempts to apply tags to these values will be silently ignored.
ansible_core-2.19.0b4/changelogs/changelog.yaml 0000644 0000000 0000000 00000162651 15010426755 020161 0 ustar 00root root ancestor: 2.18.0
releases:
2.19.0b1:
changes:
breaking_changes:
- Support for the ``toml`` library has been removed from TOML inventory parsing
and dumping. Use ``tomli`` for parsing on Python 3.10. Python 3.11 and later
have built-in support for parsing. Use ``tomli-w`` to support outputting inventory
in TOML format.
- assert - The ``quiet`` argument must be a commonly-accepted boolean value.
Previously, unrecognized values were silently treated as False.
- callback plugins - The structure of the ``exception``, ``warnings`` and ``deprecations``
values visible to callbacks has changed. Callbacks that inspect or serialize
these values may require special handling.
- conditionals - Conditional expressions that result in non-boolean values are
now an error by default. Such results often indicate unintentional use of
templates where they are not supported, resulting in a conditional that is
always true. When this option is enabled, conditional expressions which are
a literal ``None`` or empty string will evaluate as true, for backwards compatibility.
The error can be temporarily changed to a deprecation warning by enabling
the ``ALLOW_BROKEN_CONDITIONALS`` config option.
- first_found lookup - When specifying ``files`` or ``paths`` as a templated
list containing undefined values, the undefined list elements will be discarded
with a warning. Previously, the entire list would be discarded without any
warning.
- internals - The ``AnsibleLoader`` and ``AnsibleDumper`` classes for working
with YAML are now factory functions and cannot be extended.
- internals - The ``ansible.utils.native_jinja`` Python module has been removed.
- inventory - Invalid variable names provided by inventories result in an inventory
parse failure. This behavior is now consistent with other variable name usages
throughout Ansible.
- lookup plugins - Lookup plugins called as `with_(lookup)` will no longer have
the `_subdir` attribute set.
- lookup plugins - ``terms`` will always be passed to ``run`` as the first positional
arg, where previously it was sometimes passed as a keyword arg when using
``with_`` syntax.
- loops - Omit placeholders no longer leak between loop item templating and
task templating. Previously, ``omit`` placeholders could remain embedded in
loop items after templating and be used as an ``omit`` for task templating.
Now, values resolving to ``omit`` are dropped immediately when loop items
are templated. To turn missing values into an ``omit`` for task templating,
use ``| default(omit)``. This solution is backwards compatible with previous
versions of ansible-core.
- modules - Ansible modules using ``sys.excepthook`` must use a standard ``try/except``
instead.
- plugins - Any plugin that sources or creates templates must properly tag them
as trusted.
- plugins - Custom Jinja plugins that accept undefined top-level arguments must
opt in to receiving them.
- plugins - Custom Jinja plugins that use ``environment.getitem`` to retrieve
undefined values will now trigger a ``MarkerError`` exception. This exception
must be handled to allow the plugin to return a ``Marker``, or the plugin
must opt-in to accepting ``Marker`` values.
- public API - The ``ansible.vars.fact_cache.FactCache`` wrapper has been removed.
- serialization of ``omit`` sentinel - Serialization of variables containing
``omit`` sentinels (e.g., by the ``to_json`` and ``to_yaml`` filters or ``ansible-inventory``)
will fail if the variable has not completed templating. Previously, serialization
succeeded with placeholder strings emitted in the serialized output.
- set_fact - The string values "yes", "no", "true" and "false" were previously
converted (ignoring case) to boolean values when not using Jinja2 native mode.
Since Jinja2 native mode is always used, this conversion no longer occurs.
When boolean values are required, native boolean syntax should be used where
variables are defined, such as in YAML. When native boolean syntax is not
an option, the ``bool`` filter can be used to parse string values into booleans.
- template lookup - The ``convert_data`` option is deprecated and no longer
has any effect. Use the ``from_json`` filter on the lookup result instead.
- templating - Access to ``_`` prefixed attributes and methods, and methods
with known side effects, is no longer permitted. In cases where a matching
mapping key is present, the associated value will be returned instead of an
error. This increases template environment isolation and ensures more consistent
behavior between the ``.`` and ``[]`` operators.
- templating - Conditionals and lookups which use embedded inline templates
in Jinja string constants now display a warning. These templates should be
converted to their expression equivalent.
- templating - Many Jinja plugins (filters, lookups, tests) and methods previously
silently ignored undefined inputs, which often masked subtle errors. Passing
an undefined argument to a Jinja plugin or method that does not declare undefined
support now results in an undefined value.
- templating - Templates are always rendered in Jinja2 native mode. As a result,
non-string values are no longer automatically converted to strings.
- templating - Templates resulting in ``None`` are no longer automatically converted
to an empty string.
- templating - Templates with embedded inline templates that were not contained
within a Jinja string constant now result in an error, as support for multi-pass
templating was removed for security reasons. In most cases, such templates
can be easily rewritten to avoid the use of embedded inline templates.
- templating - The ``allow_unsafe_lookups`` option no longer has any effect.
Lookup plugins are responsible for tagging strings containing templates to
allow evaluation as a template.
- templating - The result of the ``range()`` global function cannot be returned
from a template- it should always be passed to a filter (e.g., ``random``).
Previously, range objects returned from an intermediate template were always
converted to a list, which is inconsistent with inline consumption of range
objects.
- templating - ``#jinja2:`` overrides in templates with invalid override names
or types are now templating errors.
bugfixes:
- Ansible will now also warn when reserved keywords are set via a module (set_fact,
include_vars, etc).
- Ansible.Basic - Fix ``required_if`` check when the option value to check is
unset or set to null.
- Correctly return ``False`` when using the ``filter`` and ``test`` Jinja tests
on plugin names which are not filters or tests, respectively. (resolves issue
https://github.com/ansible/ansible/issues/82084)
- Do not run implicit ``flush_handlers`` meta tasks when the whole play is excluded
from the run due to tags specified.
- Errors now preserve stacked error messages even when YAML is involved.
- Fix a display.debug statement with the wrong param in _get_diff_data() method
- Fix disabling SSL verification when installing collections and roles from
git repositories. If ``--ignore-certs`` isn't provided, the value for the
``GALAXY_IGNORE_CERTS`` configuration option will be used (https://github.com/ansible/ansible/issues/83326).
- Fix ipv6 pattern bug in lib/ansible/parsing/utils/addresses.py (https://github.com/ansible/ansible/issues/84237)
- Fix returning 'unreachable' for the overall task result. This prevents false
positives when a looped task has unignored unreachable items (https://github.com/ansible/ansible/issues/84019).
- 'Implicit ``meta: flush_handlers`` tasks now have a parent block to prevent
potential tracebacks when calling methods like ``get_play()`` on them internally.'
- Improve performance on large inventories by reducing the number of implicit
meta tasks.
- Jinja plugins - Errors raised will always be derived from ``AnsibleTemplatePluginError``.
- Optimize the way tasks from within ``include_tasks``/``include_role`` are
inserted into the play.
- Time out waiting on become is an unreachable error (https://github.com/ansible/ansible/issues/84468)
- Use consistent multiprocessing context for action write locks
- Use the requested error message in the ansible.module_utils.facts.timeout
timeout function instead of hardcoding one.
- Windows - add support for running on system where WDAC is in audit mode with
``Dynamic Code Security`` enabled.
- YAML parsing - The `!unsafe` tag no longer coerces non-string scalars to strings.
- "``ansible-galaxy`` \u2014 the collection dependency resolver now treats version
specifiers starting with ``!=`` as unpinned."
- '``package``/``dnf`` action plugins - provide the reason behind the failure
to gather the ``ansible_pkg_mgr`` fact to identify the package backend'
- action plugins - Action plugins that raise unhandled exceptions no longer
terminate playbook loops. Previously, exceptions raised by an action plugin
caused abnormal loop termination and loss of loop iteration results.
- ansible-config - format galaxy server configs while dumping in JSON format
(https://github.com/ansible/ansible/issues/84840).
- ansible-doc - If none of the files in files exists, path will be undefined
and a direct reference will throw an UnboundLocalError (https://github.com/ansible/ansible/pull/84464).
- ansible-galaxy - Small adjustments to URL building for ``download_url`` and
relative redirects.
- ansible-pull change detection will now work independently of callback or result
format settings.
- ansible-test - Enable the ``sys.unraisablehook`` work-around for the ``pylint``
sanity test on Python 3.11. Previously the work-around was only enabled for
Python 3.12 and later. However, the same issue has been discovered on Python
3.11.
- ansible-test - Ensure CA certificates are installed on managed FreeBSD instances.
- ansible-test - Fix support for PowerShell module_util imports with the ``-Optional``
flag.
- ansible-test - Fix support for detecting PowerShell modules importing module
utils with the newer ``#AnsibleRequires`` format.
- ansible-test - Fix traceback that occurs after an interactive command fails.
- ansible-test - Fix up coverage reporting to properly translate the temporary
path of integration test modules to the expected static test module path.
- ansible-test - Fixed traceback when handling certain YAML errors in the ``yamllint``
sanity test.
- ansible-test - Managed macOS instances now use the ``sudo_chdir`` option for
the ``sudo`` become plugin to avoid permission errors when dropping privileges.
- ansible-vault will now correctly handle `--prompt`, previously it would issue
an error about stdin if no 2nd argument was passed
- ansible_uptime_second - added ansible_uptime_seconds fact support for AIX
(https://github.com/ansible/ansible/pull/84321).
- apt_key module - prevent tests from running when apt-key was removed
- base.yml - deprecated libvirt_lxc_noseclabel config.
- build - Pin ``wheel`` in ``pyproject.toml`` to ensure compatibility with supported
``setuptools`` versions.
- config - various fixes to config lookup plugin (https://github.com/ansible/ansible/pull/84398).
- copy - refactor copy module for simplicity.
- copy action now prevents user from setting internal options.
- debconf - set empty password values (https://github.com/ansible/ansible/issues/83214).
- debug - hide loop vars in debug var display (https://github.com/ansible/ansible/issues/65856).
- default callback - Error context is now shown for failing tasks that use the
``debug`` action.
- display - The ``Display.deprecated`` method once again properly handles the
``removed=True`` argument (https://github.com/ansible/ansible/issues/82358).
- distro - add support for Linux Mint Debian Edition (LMDE) (https://github.com/ansible/ansible/issues/84934).
- distro - detect Debian as os_family for LMDE 6 (https://github.com/ansible/ansible/issues/84934).
- dnf5 - Handle forwarded exceptions from dnf5-5.2.13 where a generic ``RuntimeError``
was previously raised
- dnf5 - fix ``is_installed`` check for packages that are not installed but
listed as provided by an installed package (https://github.com/ansible/ansible/issues/84578)
- dnf5 - fix installing a package using ``state=latest`` when a binary of the
same name as the package is already installed (https://github.com/ansible/ansible/issues/84259)
- dnf5 - fix traceback when ``enable_plugins``/``disable_plugins`` is used on
``python3-libdnf5`` versions that do not support this functionality
- dnf5 - libdnf5 - use ``conf.pkg_gpgcheck`` instead of deprecated ``conf.gpgcheck``
which is used only as a fallback
- dnf5 - matching on a binary can be achieved only by specifying a full path
(https://github.com/ansible/ansible/issues/84334)
- facts - gather pagesize and calculate respective values depending upon architecture
(https://github.com/ansible/ansible/issues/84773).
- facts - skip if distribution file path is directory, instead of raising error
(https://github.com/ansible/ansible/issues/84006).
- find - skip ENOENT error code while recursively enumerating files. find module
will now be tolerant to race conditions that remove files or directories from
the target it is currently inspecting. (https://github.com/ansible/ansible/issues/84873).
- first_found lookup - Corrected return value documentation to reflect None
(not empty string) for no files found.
- gather_facts action now defaults to `ansible.legacy.setup` if `smart` was
set, no network OS was found and no other alias for `setup` was present.
- gather_facts action will now issues errors and warnings as appropriate if
a network OS is detected but no facts modules are defined for it.
- gather_facts action, will now add setup when 'smart' appears with other modules
in the FACTS_MODULES setting (#84750).
- get_url - add support for BSD-style checksum digest file (https://github.com/ansible/ansible/issues/84476).
- get_url - fix honoring ``filename`` from the ``content-disposition`` header
even when the type is ``inline`` (https://github.com/ansible/ansible/issues/83690)
- host_group_vars - fixed defining the 'key' variable if the get_vars method
is called with cache=False (https://github.com/ansible/ansible/issues/84384)
- include_vars - fix including previously undefined hash variables with hash_behaviour
merge (https://github.com/ansible/ansible/issues/84295).
- iptables - Allows the wait parameter to be used with iptables chain creation
(https://github.com/ansible/ansible/issues/84490)
- linear strategy - fix executing ``end_role`` meta tasks for each host, instead
of handling these as implicit run_once tasks (https://github.com/ansible/ansible/issues/84660).
- local connection plugin - Become timeout errors now include all received data.
Previously, the most recently-received data was discarded.
- local connection plugin - Ensure ``become`` success validation always occurs,
even when an active plugin does not set ``prompt``.
- local connection plugin - Fixed cases where the internal ``BECOME-SUCCESS``
message appeared in task output.
- local connection plugin - Fixed hang or spurious failure when data arrived
concurrently on stdout and stderr during a successful ``become`` operation
validation.
- local connection plugin - Fixed hang when a become plugin expects a prompt
but a password was not provided.
- local connection plugin - Fixed hang when an active become plugin incorrectly
signals lack of prompt.
- local connection plugin - Fixed hang when an internal become read timeout
expired before the password prompt was written.
- local connection plugin - Fixed hang when only one of stdout or stderr was
closed by the ``become_exe`` subprocess.
- local connection plugin - Fixed long timeout/hang for ``become`` plugins that
repeat their prompt on failure (e.g., ``sudo``, some ``su`` implementations).
- local connection plugin - Fixed silent ignore of ``become`` failures and loss
of task output when data arrived concurrently on stdout and stderr during
``become`` operation validation.
- local connection plugin - Fixed task output header truncation when post-become
data arrived before ``become`` operation validation had completed.
- lookup plugins - The ``terms`` arg to the ``run`` method is now always a list.
Previously, there were cases where a non-list could be received.
- module arg templating - When using a templated raw task arg and a templated
``args`` keyword, args are now merged. Previously use of templated raw task
args silently ignored all values from the templated ``args`` keyword.
- module defaults - Module defaults are no longer templated unless they are
used by a task that does not override them. Previously, all module defaults
for all modules were templated for every task.
- module respawn - limit to supported Python versions
- omitting task args - Use of omit for task args now properly falls back to
args of lower precedence, such as module defaults. Previously an omitted value
would obliterate values of lower precedence.
- package_facts module when using 'auto' will return the first package manager
found that provides an output, instead of just the first one, as this can
be foreign and not have any packages.
- psrp - Improve stderr parsing when running raw commands that emit error records
or stderr lines.
- regex_search filter - Corrected return value documentation to reflect None
(not empty string) for no match.
- respawn - use copy of env variables to update existing PYTHONPATH value (https://github.com/ansible/ansible/issues/84954).
- runas become - Fix up become logic to still get the SYSTEM token with the
most privileges when running as SYSTEM.
- sequence lookup - sequence query/lookups without positional arguments now
return a valid list if their kwargs comprise a valid sequence expression (https://github.com/ansible/ansible/issues/82921).
- service_facts - skip lines which does not contain service names in openrc
output (https://github.com/ansible/ansible/issues/84512).
- ssh - Improve the logic for parsing CLIXML data in stderr when working with
Windows host. This fixes issues when the raw stderr contains invalid UTF-8
byte sequences and improves embedded CLIXML sequences.
- ssh - Raise exception when sshpass returns error code (https://github.com/ansible/ansible/issues/58133).
- ssh - connection options were incorrectly templated during ``reset_connection``
tasks (https://github.com/ansible/ansible/pull/84238).
- stability - Fixed silent process failure on unhandled IOError/OSError under
``linear`` strategy.
- su become plugin - Ensure generated regex from ``prompt_l10n`` config values
is properly escaped.
- su become plugin - Ensure that password prompts are correctly detected in
the presence of leading output. Previously, this case resulted in a timeout
or hang.
- su become plugin - Ensure that trailing colon is expected on all ``prompt_l10n``
config values.
- sudo become plugin - The `sudo_chdir` config option allows the current directory
to be set to the specified value before executing sudo to avoid permission
errors when dropping privileges.
- sunos - remove hard coding of virtinfo command in facts gathering code (https://github.com/ansible/ansible/pull/84357).
- to_yaml/to_nice_yaml filters - Eliminated possibility of keyword arg collisions
with internally-set defaults.
- unarchive - Clamp timestamps from beyond y2038 to representible values when
unpacking zip files on platforms that use 32-bit time_t (e.g. Debian i386).
- uri - Form location correctly when the server returns a relative redirect
(https://github.com/ansible/ansible/issues/84540)
- uri - Handle HTTP exceptions raised while reading the content (https://github.com/ansible/ansible/issues/83794).
- uri - mark ``url`` as required (https://github.com/ansible/ansible/pull/83642).
- user - Create Buildroot subclass as alias to Busybox (https://github.com/ansible/ansible/issues/83665).
- user - Set timeout for passphrase interaction.
- user - Update prompt for SSH key passphrase (https://github.com/ansible/ansible/issues/84484).
- user - Use higher precedence HOME_MODE as UMASK for path provided (https://github.com/ansible/ansible/pull/84482).
- user action will now require O(force) to overwrite the public part of an ssh
key when generating ssh keys, as was already the case for the private part.
- user module now avoids changing ownership of files symlinked in provided home
dir skeleton
- vars lookup - The ``default`` substitution only applies when trying to look
up a variable which is not defined. If the variable is defined, but templates
to an undefined value, the ``default`` substitution will not apply. Use the
``default`` filter to coerce those values instead.
- wait_for_connection - a warning was displayed if any hosts used a local connection
(https://github.com/ansible/ansible/issues/84419)
deprecated_features:
- CLI - The ``--inventory-file`` option alias is deprecated. Use the ``-i``
or ``--inventory`` option instead.
- Stategy Plugins - Use of strategy plugins not provided in ``ansible.builtin``
are deprecated and do not carry any backwards compatibility guarantees going
forward. A future release will remove the ability to use external strategy
plugins. No alternative for third party strategy plugins is currently planned.
- '``ansible.module_utils.compat.datetime`` - The datetime compatibility shims
are now deprecated. They are scheduled to be removed in ``ansible-core`` v2.21.
This includes ``UTC``, ``utcfromtimestamp()`` and ``utcnow`` importable from
said module (https://github.com/ansible/ansible/pull/81874).'
- bool filter - Support for coercing unrecognized input values (including None)
has been deprecated. Consult the filter documentation for acceptable values,
or consider use of the ``truthy`` and ``falsy`` tests.
- cache plugins - The `ansible.plugins.cache.base` Python module is deprecated.
Use `ansible.plugins.cache` instead.
- callback plugins - The `v2_on_any` callback method is deprecated. Use specific
callback methods instead.
- callback plugins - The v1 callback API (callback methods not prefixed with
`v2_`) is deprecated. Use `v2_` prefixed methods instead.
- conditionals - Conditionals using Jinja templating delimiters (e.g., ``{{``,
``{%``) should be rewritten as expressions without delimiters, unless the
entire conditional value is a single template that resolves to a trusted string
expression. This is useful for dynamic indirection of conditional expressions,
but is limited to trusted literal string expressions.
- config - The ``ACTION_WARNINGS`` config has no effect. It previously disabled
command warnings, which have since been removed.
- config - The ``DEFAULT_JINJA2_NATIVE`` option has no effect. Jinja2 native
mode is now the default and only option.
- config - The ``DEFAULT_NULL_REPRESENTATION`` option has no effect. Null values
are no longer automatically converted to another value during templating of
single variable references.
- display - The ``Display.get_deprecation_message`` method has been deprecated.
Call ``Display.deprecated`` to display a deprecation message, or call it with
``removed=True`` to raise an ``AnsibleError``.
- file loading - Loading text files with ``DataLoader`` containing data that
cannot be decoded under the expected encoding is deprecated. In most cases
the encoding must be UTF-8, although some plugins allow choosing a different
encoding. Previously, invalid data was silently wrapped in Unicode surrogate
escape sequences, often resulting in later errors or other data corruption.
- first_found lookup - Splitting of file paths on ``,;:`` is deprecated. Pass
a list of paths instead. The ``split`` method on strings can be used to split
variables into a list as needed.
- interpreter discovery - The ``auto_legacy`` and ``auto_legacy_silent`` options
for ``INTERPRETER_PYTHON`` are deprecated. Use ``auto`` or ``auto_silent``
options instead, as they have the same effect.
- oneline callback - The ``oneline`` callback and its associated ad-hoc CLI
args (``-o``, ``--one-line``) are deprecated.
- paramiko - The paramiko connection plugin has been deprecated with planned
removal in 2.21.
- playbook variables - The ``play_hosts`` variable has been deprecated, use
``ansible_play_batch`` instead.
- plugin error handling - The ``AnsibleError`` constructor arg ``suppress_extended_error``
is deprecated. Using ``suppress_extended_error=True`` has the same effect
as ``show_content=False``.
- plugins - The ``listify_lookup_plugin_terms`` function is obsolete and in
most cases no longer needed.
- template lookup - The jinja2_native option is no longer used in the Ansible
Core code base. Jinja2 native mode is now the default and only option.
- templating - Support for enabling Jinja2 extensions (not plugins) has been
deprecated.
- templating - The ``ansible_managed`` variable available for certain templating
scenarios, such as the ``template`` action and ``template`` lookup has been
deprecated. Define and use a custom variable instead of relying on ``ansible_managed``.
- templating - The ``disable_lookups`` option has no effect, since plugins must
be updated to apply trust before any templating can be performed.
- to_yaml/to_nice_yaml filters - Implicit YAML dumping of vaulted value ciphertext
is deprecated. Set `dump_vault_tags` to explicitly specify the desired behavior.
- tree callback - The ``tree`` callback and its associated ad-hoc CLI args (``-t``,
``--tree``) are deprecated.
known_issues:
- templating - Any string value starting with ``#jinja2:`` which is templated
will always be interpreted as Jinja2 configuration overrides. To include this
literal value at the start of a string, a space or other character must precede
it.
- variables - Tagged values cannot be used for dictionary keys in many circumstances.
- variables - The values ``None``, ``True`` and ``False`` cannot be tagged because
they are singletons. Attempts to apply tags to these values will be silently
ignored.
major_changes:
- Jinja plugins - Jinja builtin filter and test plugins are now accessible via
their fully-qualified names ``ansible.builtin.{name}``.
- Task Execution / Forks - Forks no longer inherit stdio from the parent ``ansible-playbook``
process. ``stdout``, ``stderr``, and ``stdin`` within a worker are detached
from the terminal, and non-functional. All needs to access stdio from a fork
for controller side plugins requires use of ``Display``.
- ansible-test - Packages beneath ``module_utils`` can now contain ``__init__.py``
files.
- variables - The type system underlying Ansible's variable storage has been
significantly overhauled and formalized. Attempts to store unsupported Python
object types in variables will now result in an error.
- variables - To support new Ansible features, many variable objects are now
represented by subclasses of their respective native Python types. In most
cases, they behave indistinguishably from their original types, but some Python
libraries do not handle builtin object subclasses properly. Custom plugins
that interact with such libraries may require changes to convert and pass
the native types.
minor_changes:
- Added a -vvvvv log message indicating when a host fails to produce output
within the timeout period.
- AnsibleModule.uri - Add option ``multipart_encoding`` for ``form-multipart``
files in body to change default base64 encoding for files
- INVENTORY_IGNORE_EXTS config, removed ``ini`` from the default list, inventory
scripts using a corresponding .ini configuration are rare now and inventory.ini
files are more common. Those that need to ignore the ini files for inventory
scripts can still add it to configuration.
- Jinja plugins - Plugins can declare support for undefined values.
- Jinja2 version 3.1.0 or later is now required on the controller.
- Move ``follow_redirects`` parameter to module_utils so external modules can
reuse it.
- PlayIterator - do not return tasks from already executed roles so specific
strategy plugins do not have to do the filtering of such tasks themselves
- SSH Escalation-related -vvv log messages now include the associated host information.
- Windows - Add support for Windows Server 2025 to Ansible and as an ``ansible-test``
remote target - https://github.com/ansible/ansible/issues/84229
- Windows - refactor the async implementation to better handle errors during
bootstrapping and avoid WMI when possible.
- "``ansible-galaxy collection install`` \u2014 the collection dependency resolver
now prints out conflicts it hits during dependency resolution when it's taking
too long and it ends up backtracking a lot. It also displays suggestions on
how to help it compute the result more quickly."
- 'ansible, ansible-console, ansible-pull - add --flush-cache option (https://github.com/ansible/ansible/issues/83749).
'
- ansible-galaxy - Add support for Keycloak service accounts
- ansible-galaxy - support ``resolvelib >= 0.5.3, < 2.0.0`` (https://github.com/ansible/ansible/issues/84217).
- ansible-test - Added a macOS 15.3 remote VM, replacing 14.3.
- ansible-test - Automatically retry HTTP GET/PUT/DELETE requests on exceptions.
- ansible-test - Default to Python 3.13 in the ``base`` and ``default`` containers.
- ansible-test - Disable the ``deprecated-`` prefixed ``pylint`` rules as their
results vary by Python version.
- ansible-test - Disable the ``pep8`` sanity test rules ``E701`` and ``E704``
to improve compatibility with ``black``.
- ansible-test - Improve container runtime probe error handling. When unexpected
probe output is encountered, an error with more useful debugging information
is provided.
- ansible-test - Replace container Alpine 3.20 with 3.21.
- ansible-test - Replace container Fedora 40 with 41.
- ansible-test - Replace remote Alpine 3.20 with 3.21.
- ansible-test - Replace remote Fedora 40 with 41.
- ansible-test - Replace remote FreeBSD 13.3 with 13.5.
- ansible-test - Replace remote FreeBSD 14.1 with 14.2.
- ansible-test - Replace remote RHEL 9.4 with 9.5.
- ansible-test - Show a more user-friendly error message when a ``runme.sh``
script is not executable.
- ansible-test - The ``yamllint`` sanity test now enforces string values for
the ``!vault`` tag.
- ansible-test - Update ``nios-test-container`` to version 7.0.0.
- ansible-test - Update ``pylint`` sanity test to use version 3.3.1.
- ansible-test - Update distro containers to remove unnecessary pakages (apache2,
subversion, ruby).
- ansible-test - Update sanity test requirements to latest available versions.
- ansible-test - Update the HTTP test container.
- ansible-test - Update the PyPI test container.
- ansible-test - Update the ``base`` and ``default`` containers.
- ansible-test - Update the utility container.
- ansible-test - Use Python's ``urllib`` instead of ``curl`` for HTTP requests.
- ansible-test - When detection of the current container network fails, a warning
is now issued and execution continues. This simplifies usage in cases where
the current container cannot be inspected, such as when running in GitHub
Codespaces.
- ansible-test acme test container - bump `version to 2.3.0 `__
to include newer versions of Pebble, dependencies, and runtimes. This adds
support for ACME profiles, ``dns-account-01`` support, and some smaller improvements
(https://github.com/ansible/ansible/pull/84547).
- apt_key module - add notes to docs and errors to point at the CLI tool deprecation
by Debian and alternatives
- apt_repository module - add notes to errors to point at the CLI tool deprecation
by Debian and alternatives
- become plugins get new property 'pipelining' to show support or lack there
of for the feature.
- callback plugins - add has_option() to CallbackBase to match other functions
overloaded from AnsiblePlugin
- callback plugins - fix get_options() for CallbackBase
- copy - fix sanity test failures (https://github.com/ansible/ansible/pull/83643).
- copy - parameter ``local_follow`` was incorrectly documented as having default
value ``True`` (https://github.com/ansible/ansible/pull/83643).
- cron - Provide additional error information while writing cron file (https://github.com/ansible/ansible/issues/83223).
- csvfile - let the config system do the typecasting (https://github.com/ansible/ansible/pull/82263).
- display - Deduplication of warning and error messages considers the full content
of the message (including source and traceback contexts, if enabled). This
may result in fewer messages being omitted.
- distribution - Added openSUSE MicroOS to Suse OS family (#84685).
- dnf5, apt - add ``auto_install_module_deps`` option (https://github.com/ansible/ansible/issues/84206)
- docs - add collection name in message from which the module is being deprecated
(https://github.com/ansible/ansible/issues/84116).
- env lookup - The error message generated for a missing environment variable
when ``default`` is an undefined value (e.g. ``undef('something')``) will
contain the hint from that undefined value, except when the undefined value
is the default of ``undef()`` with no arguments. Previously, any existing
undefined hint would be ignored.
- file - enable file module to disable diff_mode (https://github.com/ansible/ansible/issues/80817).
- file - make code more readable and simple.
- filter - add support for URL-safe encoding and decoding in b64encode and b64decode
(https://github.com/ansible/ansible/issues/84147).
- find - add a checksum_algorithm parameter to specify which type of checksum
the module will return
- from_json filter - The filter accepts a ``profile`` argument, which defaults
to ``tagless``.
- handlers - Templated handler names with syntax errors, or that resolve to
``omit`` are now skipped like handlers with undefined variables in their name.
- improved error message for yaml parsing errors in plugin documentation
- local connection plugin - A new ``become_strip_preamble`` config option (default
True) was added; disable to preserve diagnostic ``become`` output in task
results.
- local connection plugin - A new ``become_success_timeout`` operation-wide
timeout config (default 10s) was added for ``become``.
- local connection plugin - When a ``become`` plugin's ``prompt`` value is a
non-string after the ``check_password_prompt`` callback has completed, no
prompt stripping will occur on stderr.
- lookup_template - add an option to trim blocks while templating (https://github.com/ansible/ansible/issues/75962).
- module - set ipv4 and ipv6 rules simultaneously in iptables module (https://github.com/ansible/ansible/issues/84404).
- module_utils - Add ``NoReturn`` type annotations to functions which never
return.
- modules - PowerShell modules can now receive ``datetime.date``, ``datetime.time``
and ``datetime.datetime`` values as ISO 8601 strings.
- modules - PowerShell modules can now receive strings sourced from inline vault-encrypted
strings.
- modules - Unhandled exceptions during Python module execution are now returned
as structured data from the target. This allows the new traceback handling
to be applied to exceptions raised on targets.
- pipelining logic has mostly moved to connection plugins so they can decide/override
settings.
- plugin error handling - When raising exceptions in an exception handler, be
sure to use ``raise ... from`` as appropriate. This supersedes the use of
the ``AnsibleError`` arg ``orig_exc`` to represent the cause. Specifying ``orig_exc``
as the cause is still permitted. Failure to use ``raise ... from`` when ``orig_exc``
is set will result in a warning. Additionally, if the two cause exceptions
do not match, a warning will be issued.
- removed harcoding of su plugin as it now works with pipelining.
- runtime-metadata sanity test - improve validation of ``action_groups`` (https://github.com/ansible/ansible/pull/83965).
- service_facts module got freebsd support added.
- ssh connection plugin - Support ``SSH_ASKPASS`` mechanism to provide passwords,
making it the default, but still offering an explicit choice to use ``sshpass``
(https://github.com/ansible/ansible/pull/83936)
- ssh connection plugin now overrides pipelining when a tty is requested.
- ssh-agent - ``ansible``, ``ansible-playbook`` and ``ansible-console`` are
capable of spawning or reusing an ssh-agent, allowing plugins to interact
with the ssh-agent. Additionally a pure python ssh-agent client has been added,
enabling easy interaction with the agent. The ssh connection plugin contains
new functionality via ``ansible_ssh_private_key`` and ``ansible_ssh_private_key_passphrase``,
for loading an SSH private key into the agent from a variable.
- templating - Access to an undefined variable from inside a lookup, filter,
or test (which raises MarkerError) no longer ends processing of the current
template. The triggering undefined value is returned as the result of the
offending plugin invocation, and the template continues to execute.
- templating - Embedding ``range()`` values in containers such as lists will
result in an error on use. Previously the value would be converted to a string
representing the range parameters, such as ``range(0, 3)``.
- templating - Handling of omitted values is now a first-class feature of the
template engine, and is usable in all Ansible Jinja template contexts. Any
template that resolves to ``omit`` is automatically removed from its parent
container during templating.
- templating - Template evaluation is lazier than in previous versions. Template
expressions which resolve only portions of a data structure no longer result
in the entire structure being templated.
- templating - Templating errors now provide more information about both the
location and context of the error, especially for deeply-nested and/or indirected
templating scenarios.
- templating - Unified ``omit`` behavior now requires that plugins calling ``Templar.template()``
handle cases where the entire template result is omitted, by catching the
``AnsibleValueOmittedError`` that is raised. Previously, this condition caused
a randomly-generated string marker to appear in the template result.
- templating - Variables of type ``set`` and ``tuple`` are now converted to
``list`` when exiting the final pass of templating.
- to_json / to_nice_json filters - The filters accept a ``profile`` argument,
which defaults to ``tagless``.
- troubleshooting - Tracebacks can be collected and displayed for most errors,
warnings, and deprecation warnings (including those generated by modules).
Tracebacks are no longer enabled with ``-vvv``; the behavior is directly configurable
via the ``DISPLAY_TRACEBACK`` config option. Module tracebacks passed to ``fail_json``
via the ``exception`` kwarg will not be included in the task result unless
error tracebacks are configured.
- undef jinja function - The ``undef`` jinja function now raises an error if
a non-string hint is given. Attempting to use an undefined hint also results
in an error, ensuring incorrect use of the function can be distinguished from
the function's normal behavior.
- validate-modules sanity test - make sure that ``module`` and ``plugin`` ``seealso``
entries use FQCNs (https://github.com/ansible/ansible/pull/84325).
- vault - improved vault filter documentation by adding missing example content
for dump_template_data.j2, refining examples for clarity, and ensuring variable
consistency (https://github.com/ansible/ansible/issues/83583).
- warnings - All warnings (including deprecation warnings) issued during a task's
execution are now accessible via the ``warnings`` and ``deprecations`` keys
on the task result.
- when the ``dict`` lookup is given a non-dict argument, show the value of the
argument and its type in the error message.
- windows - add hard minimum limit for PowerShell to 5.1. Ansible dropped support
for older versions of PowerShell in the 2.16 release but this reqirement is
now enforced at runtime.
- windows - refactor windows exec runner to improve efficiency and add better
error reporting on failures.
- winrm - Remove need for pexpect on macOS hosts when using ``kinit`` to retrieve
the Kerberos TGT. By default the code will now only use the builtin ``subprocess``
library which should handle issues with select and a high fd count and also
simplify the code.
release_summary: '| Release Date: 2025-04-14
| `Porting Guide `__
'
removed_features:
- Remove deprecated plural form of collection path (https://github.com/ansible/ansible/pull/84156).
- Removed deprecated STRING_CONVERSION_ACTION (https://github.com/ansible/ansible/issues/84220).
- encrypt - passing unsupported passlib hashtype now raises AnsibleFilterError.
- manager - remove deprecated include_delegate_to parameter from get_vars API.
- modules - Modules returning non-UTF8 strings now result in an error. The ``MODULE_STRICT_UTF8_RESPONSE``
setting can be used to disable this check.
- removed deprecated pycompat24 and compat.importlib.
- selector - remove deprecated compat.selector related files (https://github.com/ansible/ansible/pull/84155).
- windows - removed common module functions ``ConvertFrom-AnsibleJson``, ``Format-AnsibleException``
from Windows modules as they are not used and add uneeded complexity to the
code.
security_fixes:
- include_vars action - Ensure that result masking is correctly requested when
vault-encrypted files are read. (CVE-2024-8775)
- task result processing - Ensure that action-sourced result masking (``_ansible_no_log=True``)
is preserved. (CVE-2024-8775)
- templating - Ansible's template engine no longer processes Jinja templates
in strings unless they are marked as coming from a trusted source. Untrusted
strings containing Jinja template markers are ignored with a warning. Examples
of trusted sources include playbooks, vars files, and many inventory sources.
Examples of untrusted sources include module results and facts. Plugins which
have not been updated to preserve trust while manipulating strings may inadvertently
cause them to lose their trusted status.
- templating - Changes to conditional expression handling removed numerous instances
of insecure multi-pass templating (which could result in execution of untrusted
template expressions).
- user action won't allow ssh-keygen, chown and chmod to run on existing ssh
public key file, avoiding traversal on existing symlinks (CVE-2024-9902).
codename: What Is and What Should Never Be
fragments:
- 2.19.0b1_summary.yaml
- 81709-ansible-galaxy-slow-resolution-hints.yml
- 81812-ansible-galaxy-negative-spec-is-pinned.yml
- 81874-deprecate-datetime-compat.yml
- 83642-fix-sanity-ignore-for-uri.yml
- 83643-fix-sanity-ignore-for-copy.yml
- 83690-get_url-content-disposition-filename.yml
- 83700-enable-file-disable-diff.yml
- 83757-deprecate-paramiko.yml
- 83936-ssh-askpass.yml
- 83965-action-groups-schema.yml
- 84008-additional-logging.yml
- 84019-ignore_unreachable-loop.yml
- 84149-add-flush-cache-for-adhoc-commands.yml
- 84206-dnf5-apt-auto-install-module-deps.yml
- 84213-ansible-galaxy-url-building.yml
- 84229-windows-server-2025.yml
- 84238-fix-reset_connection-ssh_executable-templated.yml
- 84259-dnf5-latest-fix.yml
- 84321-added-ansible_uptime_seconds_aix.yml
- 84325-validate-modules-seealso-fqcn.yml
- 84334-dnf5-consolidate-settings.yml
- 84384-fix-undefined-key-host-group-vars.yml
- 84419-fix-wait_for_connection-warning.yml
- 84468-timeout_become_unreachable.yml
- 84473-dict-lookup-type-error-message.yml
- 84490-allow-iptables-chain-creation-with-wait.yml
- 84496-CallbackBase-get_options.yml
- 84540-uri-relative-redirect.yml
- 84547-acme-test-container.yml
- 84578-dnf5-is_installed-provides.yml
- 84660-fix-meta-end_role-linear-strategy.yml
- 84685-add-opensuse-microos.yml
- 84705-error-message-malformed-plugin-documentation.yml
- 84725-deprecate-strategy-plugins.yml
- Ansible.Basic-required_if-null.yml
- ansible-galaxy-keycloak-service-accounts.yml
- ansible-test-added-macos-15.3.yml
- ansible-test-containers.yml
- ansible-test-coverage-test-files.yml
- ansible-test-curl.yml
- ansible-test-fix-command-traceback.yml
- ansible-test-freebsd-nss.yml
- ansible-test-network-detection.yml
- ansible-test-nios-container.yml
- ansible-test-no-exec-script.yml
- ansible-test-probe-error-handling.yml
- ansible-test-pylint-fix.yml
- ansible-test-remotes.yml
- ansible-test-update.yml
- apt_key_bye.yml
- become-runas-system-deux.yml
- buildroot.yml
- compat_removal.yml
- config.yml
- config_dump.yml
- copy_validate_input.yml
- cron_err.yml
- csvfile-col.yml
- cve-2024-8775.yml
- darwin_pagesize.yml
- debconf_empty_password.yml
- deprecated.yml
- distro_LMDE_6.yml
- dnf5-exception-forwarding.yml
- dnf5-plugins-compat.yml
- dnf5-remove-usage-deprecated-option.yml
- feature-uri-add-option-multipart-encoding.yml
- file_simplify.yml
- find-checksum.yml
- find_enoent.yml
- fix-ansible-galaxy-ignore-certs.yml
- fix-cli-doc-path_undefined.yaml
- fix-display-bug-in-action-plugin.yml
- fix-include_vars-merge-hash.yml
- fix-ipv6-pattern.yml
- fix-is-filter-is-test.yml
- fix-lookup-sequence-keyword-args-only.yml
- fix-module-utils-facts-timeout.yml
- fix_errors.yml
- follow_redirects_url.yml
- gather_facts_netos_fixes.yml
- gather_facts_smart_fix.yml
- get_url_bsd_style_digest.yml
- hide-loop-vars-debug-vars.yml
- implicit_flush_handlers_parents.yml
- include_delegate_to.yml
- interpreter-discovery-auto-legacy.yml
- jinja-version.yml
- libvirt_lxc.yml
- local-become-fixes.yml
- lookup_config.yml
- macos-correct-lock.yml
- no-inherit-stdio.yml
- no-return.yml
- openrc-status.yml
- os_family.yml
- package-dnf-action-plugins-facts-fail-msg.yml
- package_facts_fix.yml
- passlib.yml
- pin-wheel.yml
- pipelining_refactor.yml
- playiterator-add_tasks-optimize.yml
- ps-import-sanity.yml
- pull_changed_fix.yml
- remove_ini_ignored_dir.yml
- reserved_module_chekc.yml
- respawn-min-python.yml
- respawn_os_env.yml
- selector_removal.yml
- service_facts_fbsd.yml
- set_ipv4_and_ipv6_simultaneously.yml
- simplify-copy-module.yml
- skip-handlers-tagged-play.yml
- skip-implicit-flush_handlers-no-notify.yml
- skip-role-task-iterator.yml
- ssh-agent.yml
- ssh-clixml.yml
- ssh_raise_exception.yml
- string_conversion.yml
- sunos_virtinfo.yml
- templates_types_datatagging.yml
- toml-library-support-dropped.yml
- trim_blocks.yml
- unarchive_timestamp_t32.yaml
- update-resolvelib-lt-2_0_0.yml
- uri_httpexception.yml
- url_safe_b64_encode_decode.yml
- user_action_fix.yml
- user_module.yml
- user_passphrase.yml
- user_ssh_fix.yml
- v2.19.0-initial-commit.yaml
- vault_cli_fix.yml
- vault_docs_fix.yaml
- win-async-refactor.yml
- win-wdac-audit.yml
- windows-exec.yml
- winrm-kinit-pexpect.yml
release_date: '2025-04-14'
2.19.0b2:
changes:
bugfixes:
- Remove use of `required` parameter in `get_bin_path` which has been deprecated.
- ansible-doc - fix indentation for first line of descriptions of suboptions
and sub-return values (https://github.com/ansible/ansible/pull/84690).
- ansible-doc - fix line wrapping for first line of description of options and
return values (https://github.com/ansible/ansible/pull/84690).
minor_changes:
- comment filter - Improve the error message shown when an invalid ``style``
argument is provided.
release_summary: '| Release Date: 2025-04-24
| `Porting Guide `__
'
codename: What Is and What Should Never Be
fragments:
- 2.19.0b2_summary.yaml
- 84690-ansible-doc-indent-wrapping.yml
- comment_fail.yml
- get_bin_path-remove-use-of-deprecated-param.yml
release_date: '2025-04-23'
2.19.0b3:
changes:
bugfixes:
- Ansible will now ensure predictable permissions on remote artifacts, until
now it only ensured executable and relied on system masks for the rest.
- dnf5 - avoid generating excessive transaction entries in the dnf5 history
(https://github.com/ansible/ansible/issues/85046)
deprecated_features:
- Passing a ``warnings` or ``deprecations`` key to ``exit_json`` or ``fail_json``
is deprecated. Use ``AnsibleModule.warn`` or ``AnsibleModule.deprecate`` instead.
- plugins - Accessing plugins with ``_``-prefixed filenames without the ``_``
prefix is deprecated.
minor_changes:
- ansible-config will now show internal, but not test configuration entries.
This allows for debugging but still denoting the configurations as internal
use only (_ prefix).
- ansible-test - Improved ``pylint`` checks for Ansible-specific deprecation
functions.
- ansible-test - Use the ``-t`` option to set the stop timeout when stopping
a container. This avoids use of the ``--time`` option which was deprecated
in Docker v28.0.
- collection metadata - The collection loader now parses scalar values from
``meta/runtime.yml`` as strings. This avoids issues caused by unquoted values
such as versions or dates being parsed as types other than strings.
- deprecation warnings - Deprecation warning APIs automatically capture the
identity of the deprecating plugin. The ``collection_name`` argument is only
required to correctly attribute deprecations that occur in module_utils or
other non-plugin code.
- deprecation warnings - Improved deprecation messages to more clearly indicate
the affected content, including plugin name when available.
- deprecations - Collection name strings not of the form ``ns.coll`` passed
to deprecation API functions will result in an error.
- deprecations - Removed support for specifying deprecation dates as a ``datetime.date``,
which was included in an earlier 2.19 pre-release.
- deprecations - Some argument names to ``deprecate_value`` for consistency
with existing APIs. An earlier 2.19 pre-release included a ``removal_`` prefix
on the ``date`` and ``version`` arguments.
- modules - The ``AnsibleModule.deprecate`` function no longer sends deprecation
messages to the target host's logging system.
release_summary: '| Release Date: 2025-05-06
| `Porting Guide `__
'
codename: What Is and What Should Never Be
fragments:
- 2.19.0b3_summary.yaml
- 85046-dnf5-history-entries.yml
- ansible-test-container-stop.yml
- config_priv.yml
- deprecator.yml
- ensure_remote_perms.yml
release_date: '2025-05-06'
2.19.0b4:
changes:
bugfixes:
- ansible-test - Updated the ``pylint`` sanity test to skip some deprecation
validation checks when all arguments are dynamic.
- config - Preserve or apply Origin tag to values returned by config.
- config - Prevented fatal errors when ``MODULE_IGNORE_EXTS`` configuration
was set.
- config - Templating failures on config defaults now issue a warning. Previously,
failures silently returned an unrendered and untrusted template to the caller.
- config - ``ensure_type`` correctly propagates trust and other tags on returned
values.
- config - ``ensure_type`` now converts mappings to ``dict`` when requested,
instead of returning the mapping.
- config - ``ensure_type`` now converts sequences to ``list`` when requested,
instead of returning the sequence.
- config - ``ensure_type`` now correctly errors when ``pathlist`` or ``pathspec``
types encounter non-string list items.
- config - ``ensure_type`` now reports an error when ``bytes`` are provided
for any known ``value_type``. Previously, the behavior was undefined, but
often resulted in an unhandled exception or incorrect return type.
- config - ``ensure_type`` with expected type ``int`` now properly converts
``True`` and ``False`` values to ``int``. Previously, these values were silently
returned unmodified.
- convert_bool.boolean API conversion function - Unhashable values passed to
``boolean`` behave like other non-boolean convertible values, returning False
or raising ``TypeError`` depending on the value of ``strict``. Previously,
unhashable values always raised ``ValueError`` due to an invalid set membership
check.
- dnf5 - when ``bugfix`` and/or ``security`` is specified, skip packages that
do not have any such updates, even for new versions of libdnf5 where this
functionality changed and it is considered failure
- plugin loader - Apply template trust to strings loaded from plugin configuration
definitions and doc fragments.
- template action - Template files where the entire file's output renders as
``None`` are no longer emitted as the string "None", but instead render to
an empty file as in previous releases.
minor_changes:
- facts - add "CloudStack KVM Hypervisor" for Linux VM in virtual facts (https://github.com/ansible/ansible/issues/85089).
- modules - use ``AnsibleModule.warn`` instead of passing ``warnings`` to ``exit_json``
or ``fail_json`` which is deprecated.
release_summary: '| Release Date: 2025-05-12
| `Porting Guide `__
'
codename: What Is and What Should Never Be
fragments:
- 2.19.0b4_summary.yaml
- 85117-add-cloudstack-kvm-for-linux-facts.yml
- ansible-test-pylint-deprecated-fix.yml
- dnf5-advisory-type.yml
- ensure_type.yml
- plugin-loader-trust-docs.yml
- preserve_config_origin.yml
- remove-warnings-retval.yml
- template-none.yml
release_date: '2025-05-12'
ansible_core-2.19.0b4/lib/ 0000755 0000000 0000000 00000000000 15010426755 013767 5 ustar 00root root ansible_core-2.19.0b4/lib/ansible/ 0000755 0000000 0000000 00000000000 15010426755 015404 5 ustar 00root root ansible_core-2.19.0b4/lib/ansible/__init__.py 0000644 0000000 0000000 00000002277 15010426755 017525 0 ustar 00root root # (c) 2012-2014, Michael DeHaan
#
# 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 .
from __future__ import annotations
# make vendored top-level modules accessible EARLY
import ansible._vendor
# Note: Do not add any code to this file. The ansible module may be
# a namespace package when using Ansible-2.1+ Anything in this file may not be
# available if one of the other packages in the namespace is loaded first.
#
# This is for backwards compat. Code should be ported to get these from
# ansible.release instead of from here.
from ansible.release import __version__, __author__
ansible_core-2.19.0b4/lib/ansible/__main__.py 0000644 0000000 0000000 00000001434 15010426755 017500 0 ustar 00root root # Copyright: (c) 2021, Matt Martz
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import annotations
import argparse
from importlib.metadata import distribution
def _short_name(name):
return name.removeprefix('ansible-').replace('ansible', 'adhoc')
def main():
dist = distribution('ansible-core')
ep_map = {_short_name(ep.name): ep for ep in dist.entry_points if ep.group == 'console_scripts'}
parser = argparse.ArgumentParser(prog='python -m ansible', add_help=False)
parser.add_argument('entry_point', choices=list(ep_map))
args, extra = parser.parse_known_args()
main = ep_map[args.entry_point].load()
main([args.entry_point] + extra)
if __name__ == '__main__':
main()
ansible_core-2.19.0b4/lib/ansible/_internal/ 0000755 0000000 0000000 00000000000 15010426755 017357 5 ustar 00root root ansible_core-2.19.0b4/lib/ansible/_internal/__init__.py 0000644 0000000 0000000 00000004241 15010426755 021471 0 ustar 00root root from __future__ import annotations
import importlib
import typing as t
from ansible.module_utils import _internal
from ansible.module_utils._internal._json import _profiles
def get_controller_serialize_map() -> dict[type, t.Callable]:
"""
Injected into module_utils code to augment serialization maps with controller-only types.
This implementation replaces the no-op version in module_utils._internal in controller contexts.
"""
from ansible._internal._templating import _lazy_containers
from ansible.parsing.vault import EncryptedString
return {
_lazy_containers._AnsibleLazyTemplateDict: _profiles._JSONSerializationProfile.discard_tags,
_lazy_containers._AnsibleLazyTemplateList: _profiles._JSONSerializationProfile.discard_tags,
EncryptedString: str, # preserves tags since this is an instance of EncryptedString; if tags should be discarded from str, another entry will handle it
}
def import_controller_module(module_name: str, /) -> t.Any:
"""
Injected into module_utils code to import and return the specified module.
This implementation replaces the no-op version in module_utils._internal in controller contexts.
"""
return importlib.import_module(module_name)
_T = t.TypeVar('_T')
def experimental(obj: _T) -> _T:
"""
Decorator for experimental types and methods outside the `_internal` package which accept or expose internal types.
As with internal APIs, these are subject to change at any time without notice.
"""
return obj
def setup() -> None:
"""No-op function to ensure that side-effect only imports of this module are not flagged/removed as 'unused'."""
# DTFIX-RELEASE: this is really fragile- disordered/incorrect imports (among other things) can mess it up. Consider a hosting-env-managed context
# with an enum with at least Controller/Target/Unknown values, and possibly using lazy-init module shims or some other mechanism to allow controller-side
# notification/augmentation of this kind of metadata.
_internal.get_controller_serialize_map = get_controller_serialize_map
_internal.import_controller_module = import_controller_module
_internal.is_controller = True
ansible_core-2.19.0b4/lib/ansible/_internal/_ansiballz.py 0000644 0000000 0000000 00000026601 15010426755 022054 0 ustar 00root root # shebang placeholder
from __future__ import annotations
import datetime
# For test-module.py script to tell this is a ANSIBALLZ_WRAPPER
_ANSIBALLZ_WRAPPER = True
# This code is part of Ansible, but is an independent component.
# The code in this particular templatable string, and this templatable string
# only, is BSD licensed. Modules which end up using this snippet, which is
# dynamically combined together by Ansible still belong to the author of the
# module, and they may assign their own license to the complete work.
#
# Copyright (c), James Cammarata, 2016
# Copyright (c), Toshio Kuratomi, 2016
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
def _ansiballz_main(
zipdata: str,
ansible_module: str,
module_fqn: str,
params: str,
profile: str,
date_time: datetime.datetime,
coverage_config: str | None,
coverage_output: str | None,
rlimit_nofile: int,
) -> None:
import os
import os.path
# Access to the working directory is required by Python when using pipelining, as well as for the coverage module.
# Some platforms, such as macOS, may not allow querying the working directory when using become to drop privileges.
try:
os.getcwd()
except OSError:
try:
os.chdir(os.path.expanduser('~'))
except OSError:
os.chdir('/')
if rlimit_nofile:
import resource
existing_soft, existing_hard = resource.getrlimit(resource.RLIMIT_NOFILE)
# adjust soft limit subject to existing hard limit
requested_soft = min(existing_hard, rlimit_nofile)
if requested_soft != existing_soft:
try:
resource.setrlimit(resource.RLIMIT_NOFILE, (requested_soft, existing_hard))
except ValueError:
# some platforms (eg macOS) lie about their hard limit
pass
import sys
import __main__
# For some distros and python versions we pick up this script in the temporary
# directory. This leads to problems when the ansible module masks a python
# library that another import needs. We have not figured out what about the
# specific distros and python versions causes this to behave differently.
#
# Tested distros:
# Fedora23 with python3.4 Works
# Ubuntu15.10 with python2.7 Works
# Ubuntu15.10 with python3.4 Fails without this
# Ubuntu16.04.1 with python3.5 Fails without this
# To test on another platform:
# * use the copy module (since this shadows the stdlib copy module)
# * Turn off pipelining
# * Make sure that the destination file does not exist
# * ansible ubuntu16-test -m copy -a 'src=/etc/motd dest=/var/tmp/m'
# This will traceback in shutil. Looking at the complete traceback will show
# that shutil is importing copy which finds the ansible module instead of the
# stdlib module
scriptdir = None
try:
scriptdir = os.path.dirname(os.path.realpath(__main__.__file__))
except (AttributeError, OSError):
# Some platforms don't set __file__ when reading from stdin
# OSX raises OSError if using abspath() in a directory we don't have
# permission to read (realpath calls abspath)
pass
# Strip cwd from sys.path to avoid potential permissions issues
excludes = {'', '.', scriptdir}
sys.path = [p for p in sys.path if p not in excludes]
import base64
import shutil
import tempfile
import zipfile
def invoke_module(modlib_path: str, json_params: bytes) -> None:
# When installed via setuptools (including python setup.py install),
# ansible may be installed with an easy-install.pth file. That file
# may load the system-wide install of ansible rather than the one in
# the module. sitecustomize is the only way to override that setting.
z = zipfile.ZipFile(modlib_path, mode='a')
# py3: modlib_path will be text, py2: it's bytes. Need bytes at the end
sitecustomize = u'import sys\\nsys.path.insert(0,"%s")\\n' % modlib_path
sitecustomize = sitecustomize.encode('utf-8')
# Use a ZipInfo to work around zipfile limitation on hosts with
# clocks set to a pre-1980 year (for instance, Raspberry Pi)
zinfo = zipfile.ZipInfo()
zinfo.filename = 'sitecustomize.py'
zinfo.date_time = date_time.utctimetuple()[:6]
z.writestr(zinfo, sitecustomize)
z.close()
# Put the zipped up module_utils we got from the controller first in the python path so that we
# can monkeypatch the right basic
sys.path.insert(0, modlib_path)
from ansible.module_utils._internal._ansiballz import run_module
run_module(
json_params=json_params,
profile=profile,
module_fqn=module_fqn,
modlib_path=modlib_path,
coverage_config=coverage_config,
coverage_output=coverage_output,
)
def debug(command: str, modlib_path: str, json_params: bytes) -> None:
# The code here normally doesn't run. It's only used for debugging on the
# remote machine.
#
# The subcommands in this function make it easier to debug ansiballz
# modules. Here's the basic steps:
#
# Run ansible with the environment variable: ANSIBLE_KEEP_REMOTE_FILES=1 and -vvv
# to save the module file remotely::
# $ ANSIBLE_KEEP_REMOTE_FILES=1 ansible host1 -m ping -a 'data=october' -vvv
#
# Part of the verbose output will tell you where on the remote machine the
# module was written to::
# [...]
# SSH: EXEC ssh -C -q -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o
# PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o
# ControlPath=/home/badger/.ansible/cp/ansible-ssh-%h-%p-%r -tt rhel7 '/bin/sh -c '"'"'LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8
# LC_MESSAGES=en_US.UTF-8 /usr/bin/python /home/badger/.ansible/tmp/ansible-tmp-1461173013.93-9076457629738/ping'"'"''
# [...]
#
# Login to the remote machine and run the module file via from the previous
# step with the explode subcommand to extract the module payload into
# source files::
# $ ssh host1
# $ /usr/bin/python /home/badger/.ansible/tmp/ansible-tmp-1461173013.93-9076457629738/ping explode
# Module expanded into:
# /home/badger/.ansible/tmp/ansible-tmp-1461173408.08-279692652635227/ansible
#
# You can now edit the source files to instrument the code or experiment with
# different parameter values. When you're ready to run the code you've modified
# (instead of the code from the actual zipped module), use the execute subcommand like this::
# $ /usr/bin/python /home/badger/.ansible/tmp/ansible-tmp-1461173013.93-9076457629738/ping execute
# Okay to use __file__ here because we're running from a kept file
basedir = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'debug_dir')
args_path = os.path.join(basedir, 'args')
if command == 'explode':
# transform the ZIPDATA into an exploded directory of code and then
# print the path to the code. This is an easy way for people to look
# at the code on the remote machine for debugging it in that
# environment
z = zipfile.ZipFile(modlib_path)
for filename in z.namelist():
if filename.startswith('/'):
raise Exception('Something wrong with this module zip file: should not contain absolute paths')
dest_filename = os.path.join(basedir, filename)
if dest_filename.endswith(os.path.sep) and not os.path.exists(dest_filename):
os.makedirs(dest_filename)
else:
directory = os.path.dirname(dest_filename)
if not os.path.exists(directory):
os.makedirs(directory)
with open(dest_filename, 'wb') as writer:
writer.write(z.read(filename))
# write the args file
with open(args_path, 'wb') as writer:
writer.write(json_params)
print('Module expanded into:')
print(basedir)
elif command == 'execute':
# Execute the exploded code instead of executing the module from the
# embedded ZIPDATA. This allows people to easily run their modified
# code on the remote machine to see how changes will affect it.
# Set pythonpath to the debug dir
sys.path.insert(0, basedir)
# read in the args file which the user may have modified
with open(args_path, 'rb') as reader:
json_params = reader.read()
from ansible.module_utils._internal._ansiballz import run_module
run_module(
json_params=json_params,
profile=profile,
module_fqn=module_fqn,
modlib_path=modlib_path,
)
else:
print(f'FATAL: Unknown debug command {command!r}. Doing nothing.')
#
# See comments in the debug() method for information on debugging
#
encoded_params = params.encode()
# There's a race condition with the controller removing the
# remote_tmpdir and this module executing under async. So we cannot
# store this in remote_tmpdir (use system tempdir instead)
# Only need to use [ansible_module]_payload_ in the temp_path until we move to zipimport
# (this helps ansible-test produce coverage stats)
temp_path = tempfile.mkdtemp(prefix='ansible_' + ansible_module + '_payload_')
try:
zipped_mod = os.path.join(temp_path, 'ansible_' + ansible_module + '_payload.zip')
with open(zipped_mod, 'wb') as modlib:
modlib.write(base64.b64decode(zipdata))
if len(sys.argv) == 2:
debug(sys.argv[1], zipped_mod, encoded_params)
else:
invoke_module(zipped_mod, encoded_params)
finally:
shutil.rmtree(temp_path, ignore_errors=True)
ansible_core-2.19.0b4/lib/ansible/_internal/_collection_proxy.py 0000644 0000000 0000000 00000002323 15010426755 023464 0 ustar 00root root from __future__ import annotations as _annotations
import collections.abc as _c
import typing as _t
_T_co = _t.TypeVar('_T_co', covariant=True)
class SequenceProxy(_c.Sequence[_T_co]):
"""A read-only sequence proxy."""
# DTFIX-RELEASE: needs unit test coverage
__slots__ = ('__value',)
def __init__(self, value: _c.Sequence[_T_co]) -> None:
self.__value = value
@_t.overload
def __getitem__(self, index: int) -> _T_co: ...
@_t.overload
def __getitem__(self, index: slice) -> _c.Sequence[_T_co]: ...
def __getitem__(self, index: int | slice) -> _T_co | _c.Sequence[_T_co]:
if isinstance(index, slice):
return self.__class__(self.__value[index])
return self.__value[index]
def __len__(self) -> int:
return len(self.__value)
def __contains__(self, item: object) -> bool:
return item in self.__value
def __iter__(self) -> _t.Iterator[_T_co]:
yield from self.__value
def __reversed__(self) -> _c.Iterator[_T_co]:
return reversed(self.__value)
def index(self, *args) -> int:
return self.__value.index(*args)
def count(self, value: object) -> int:
return self.__value.count(value)
ansible_core-2.19.0b4/lib/ansible/_internal/_datatag/ 0000755 0000000 0000000 00000000000 15010426755 021123 5 ustar 00root root ansible_core-2.19.0b4/lib/ansible/_internal/_datatag/__init__.py 0000644 0000000 0000000 00000000000 15010426755 023222 0 ustar 00root root ansible_core-2.19.0b4/lib/ansible/_internal/_datatag/_tags.py 0000644 0000000 0000000 00000012074 15010426755 022576 0 ustar 00root root from __future__ import annotations
import dataclasses
import os
import types
import typing as t
from ansible.module_utils._internal._datatag import _tag_dataclass_kwargs, AnsibleDatatagBase, AnsibleSingletonTagBase
@dataclasses.dataclass(**_tag_dataclass_kwargs)
class Origin(AnsibleDatatagBase):
"""
A tag that stores origin metadata for a tagged value, intended for forensic/diagnostic use.
Origin metadata should not be used to make runtime decisions, as it is not guaranteed to be present or accurate.
Setting both `path` and `line_num` can result in diagnostic display of referenced file contents.
Either `path` or `description` must be present.
"""
path: str | None = None
"""The path from which the tagged content originated."""
description: str | None = None
"""A description of the origin, for display to users."""
line_num: int | None = None
"""An optional line number, starting at 1."""
col_num: int | None = None
"""An optional column number, starting at 1."""
UNKNOWN: t.ClassVar[t.Self]
@classmethod
def get_or_create_tag(cls, value: t.Any, path: str | os.PathLike | None) -> Origin:
"""Return the tag from the given value, creating a tag from the provided path if no tag was found."""
if not (origin := cls.get_tag(value)):
if path:
origin = Origin(path=str(path)) # convert tagged strings and path-like values to a native str
else:
origin = Origin.UNKNOWN
return origin
def replace(
self,
path: str | types.EllipsisType = ...,
description: str | types.EllipsisType = ...,
line_num: int | None | types.EllipsisType = ...,
col_num: int | None | types.EllipsisType = ...,
) -> t.Self:
"""Return a new origin based on an existing one, with the given fields replaced."""
return dataclasses.replace(
self,
**{
key: value
for key, value in dict(
path=path,
description=description,
line_num=line_num,
col_num=col_num,
).items()
if value is not ...
}, # type: ignore[arg-type]
)
def _post_validate(self) -> None:
if self.path:
if not self.path.startswith('/'):
raise RuntimeError('The `src` field must be an absolute path.')
elif not self.description:
raise RuntimeError('The `src` or `description` field must be specified.')
def __str__(self) -> str:
"""Renders the origin in the form of path:line_num:col_num, omitting missing/invalid elements from the right."""
if self.path:
value = self.path
else:
value = self.description
if self.line_num and self.line_num > 0:
value += f':{self.line_num}'
if self.col_num and self.col_num > 0:
value += f':{self.col_num}'
if self.path and self.description:
value += f' ({self.description})'
return value
Origin.UNKNOWN = Origin(description='')
@dataclasses.dataclass(**_tag_dataclass_kwargs)
class VaultedValue(AnsibleDatatagBase):
"""Tag for vault-encrypted strings that carries the original ciphertext for round-tripping."""
ciphertext: str
def _get_tag_to_propagate(self, src: t.Any, value: object, *, value_type: t.Optional[type] = None) -> t.Self | None:
# Since VaultedValue stores the encrypted representation of the value on which it is tagged,
# it is incorrect to propagate the tag to a value which is not equal to the original.
# If the tag were copied to another value and subsequently serialized as the original encrypted value,
# the result would then differ from the value on which the tag was applied.
# Comparisons which can trigger an exception are indicative of a bug and should not be handled here.
# For example:
# * When `src` is an undecryptable `EncryptedString` -- it is not valid to apply this tag to that type.
# * When `value` is a `Marker` -- this requires a templating, but vaulted values do not support templating.
if src == value: # assume the tag was correctly applied to src
return self # same plaintext value, tag propagation with same ciphertext is safe
return self.get_tag(value) # different value, preserve the existing tag, if any
@dataclasses.dataclass(**_tag_dataclass_kwargs)
class TrustedAsTemplate(AnsibleSingletonTagBase):
"""
Indicates the tagged string is trusted to parse and render as a template.
Do *NOT* apply this tag to data from untrusted sources, as this would allow code injection during templating.
"""
@dataclasses.dataclass(**_tag_dataclass_kwargs)
class SourceWasEncrypted(AnsibleSingletonTagBase):
"""
For internal use only.
Indicates the tagged value was sourced from an encrypted file.
Currently applied only by DataLoader.get_text_file_contents() and by extension DataLoader.load_from_file().
"""
ansible_core-2.19.0b4/lib/ansible/_internal/_datatag/_utils.py 0000644 0000000 0000000 00000001416 15010426755 022776 0 ustar 00root root from __future__ import annotations
from ansible.module_utils._internal._datatag import AnsibleTagHelper
def str_problematic_strip(value: str) -> str:
"""
Return a copy of `value` with leading and trailing whitespace removed.
Used where `str.strip` is needed, but tags must be preserved *AND* the stripping behavior likely shouldn't exist.
If the stripping behavior is non-problematic, use `AnsibleTagHelper.tag_copy` around `str.strip` instead.
"""
if (stripped_value := value.strip()) == value:
return value
# FUTURE: consider deprecating some/all usages of this method; they generally imply a code smell or pattern we shouldn't be supporting
stripped_value = AnsibleTagHelper.tag_copy(value, stripped_value)
return stripped_value
ansible_core-2.19.0b4/lib/ansible/_internal/_datatag/_wrappers.py 0000644 0000000 0000000 00000002161 15010426755 023477 0 ustar 00root root from __future__ import annotations
import io
import typing as _t
from .._wrapt import ObjectProxy
from ...module_utils._internal import _datatag
class TaggedStreamWrapper(ObjectProxy):
"""
Janky proxy around IOBase to allow streams to carry tags and support basic interrogation by the tagging API.
Most tagging operations will have undefined behavior for this type.
"""
_self__ansible_tags_mapping: _datatag._AnsibleTagsMapping
def __init__(self, stream: io.IOBase, tags: _datatag.AnsibleDatatagBase | _t.Iterable[_datatag.AnsibleDatatagBase]) -> None:
super().__init__(stream)
tag_list: list[_datatag.AnsibleDatatagBase]
# noinspection PyProtectedMember
if type(tags) in _datatag._known_tag_types:
tag_list = [tags] # type: ignore[list-item]
else:
tag_list = list(tags) # type: ignore[arg-type]
self._self__ansible_tags_mapping = _datatag._AnsibleTagsMapping((type(tag), tag) for tag in tag_list)
@property
def _ansible_tags_mapping(self) -> _datatag._AnsibleTagsMapping:
return self._self__ansible_tags_mapping
ansible_core-2.19.0b4/lib/ansible/_internal/_errors/ 0000755 0000000 0000000 00000000000 15010426755 021032 5 ustar 00root root ansible_core-2.19.0b4/lib/ansible/_internal/_errors/__init__.py 0000644 0000000 0000000 00000000000 15010426755 023131 0 ustar 00root root ansible_core-2.19.0b4/lib/ansible/_internal/_errors/_captured.py 0000644 0000000 0000000 00000011467 15010426755 023363 0 ustar 00root root from __future__ import annotations
import dataclasses
import typing as t
from ansible.errors import AnsibleRuntimeError
from ansible.module_utils.common.messages import ErrorSummary, Detail, _dataclass_kwargs
class AnsibleCapturedError(AnsibleRuntimeError):
"""An exception representing error detail captured in another context where the error detail must be serialized to be preserved."""
context: t.ClassVar[str]
def __init__(
self,
*,
obj: t.Any = None,
error_summary: ErrorSummary,
) -> None:
super().__init__(
obj=obj,
)
self._error_summary = error_summary
@property
def error_summary(self) -> ErrorSummary:
return self._error_summary
class AnsibleResultCapturedError(AnsibleCapturedError):
"""An exception representing error detail captured in a foreign context where an action/module result dictionary is involved."""
def __init__(self, error_summary: ErrorSummary, result: dict[str, t.Any]) -> None:
super().__init__(error_summary=error_summary)
self._result = result
@classmethod
def maybe_raise_on_result(cls, result: dict[str, t.Any]) -> None:
"""Normalize the result and raise an exception if the result indicated failure."""
if error_summary := cls.normalize_result_exception(result):
raise error_summary.error_type(error_summary, result)
@classmethod
def find_first_remoted_error(cls, exception: BaseException) -> t.Self | None:
"""Find the first captured module error in the cause chain, starting with the given exception, returning None if not found."""
while exception:
if isinstance(exception, cls):
return exception
exception = exception.__cause__
return None
@classmethod
def normalize_result_exception(cls, result: dict[str, t.Any]) -> CapturedErrorSummary | None:
"""
Normalize the result `exception`, if any, to be a `CapturedErrorSummary` instance.
If a new `CapturedErrorSummary` was created, the `error_type` will be `cls`.
The `exception` key will be removed if falsey.
A `CapturedErrorSummary` instance will be returned if `failed` is truthy.
"""
if type(cls) is AnsibleResultCapturedError: # pylint: disable=unidiomatic-typecheck
raise TypeError('The normalize_result_exception method cannot be called on the AnsibleCapturedError base type, use a derived type.')
if not isinstance(result, dict):
raise TypeError(f'Malformed result. Received {type(result)} instead of {dict}.')
failed = result.get('failed') # DTFIX-FUTURE: warn if failed is present and not a bool, or exception is present without failed being True
exception = result.pop('exception', None)
if not failed and not exception:
return None
if isinstance(exception, CapturedErrorSummary):
error_summary = exception
elif isinstance(exception, ErrorSummary):
error_summary = CapturedErrorSummary(
details=exception.details,
formatted_traceback=cls._normalize_traceback(exception.formatted_traceback),
error_type=cls,
)
else:
# translate non-ErrorDetail errors
error_summary = CapturedErrorSummary(
details=(Detail(msg=str(result.get('msg', 'Unknown error.'))),),
formatted_traceback=cls._normalize_traceback(exception),
error_type=cls,
)
result.update(exception=error_summary)
return error_summary if failed else None # even though error detail was normalized, only return it if the result indicated failure
@classmethod
def _normalize_traceback(cls, value: object | None) -> str | None:
"""Normalize the provided traceback value, returning None if it is falsey."""
if not value:
return None
value = str(value).rstrip()
if not value:
return None
return value + '\n'
class AnsibleActionCapturedError(AnsibleResultCapturedError):
"""An exception representing error detail sourced directly by an action in its result dictionary."""
_default_message = 'Action failed.'
context = 'action'
class AnsibleModuleCapturedError(AnsibleResultCapturedError):
"""An exception representing error detail captured in a module context and returned from an action's result dictionary."""
_default_message = 'Module failed.'
context = 'target'
@dataclasses.dataclass(**_dataclass_kwargs)
class CapturedErrorSummary(ErrorSummary):
# DTFIX-RELEASE: where to put this, name, etc. since it shows up in results, it's not exactly private (and contains a type ref to an internal type)
error_type: type[AnsibleResultCapturedError] | None = None
ansible_core-2.19.0b4/lib/ansible/_internal/_errors/_handler.py 0000644 0000000 0000000 00000006577 15010426755 023177 0 ustar 00root root from __future__ import annotations
import contextlib
import enum
import typing as t
from ansible.utils.display import Display
from ansible.constants import config
display = Display()
# FUTURE: add sanity test to detect use of skip_on_ignore without Skippable (and vice versa)
class ErrorAction(enum.Enum):
"""Action to take when an error is encountered."""
IGNORE = enum.auto()
WARNING = enum.auto()
ERROR = enum.auto()
@classmethod
def from_config(cls, setting: str, variables: dict[str, t.Any] | None = None) -> t.Self:
"""Return an `ErrorAction` enum from the specified Ansible config setting."""
return cls[config.get_config_value(setting, variables=variables).upper()]
class _SkipException(BaseException):
"""Internal flow control exception for skipping code blocks within a `Skippable` context manager."""
def __init__(self) -> None:
super().__init__('Skipping ignored action due to use of `skip_on_ignore`. It is a bug to encounter this message outside of debugging.')
class _SkippableContextManager:
"""Internal context manager to support flow control for skipping code blocks."""
def __enter__(self) -> None:
pass
def __exit__(self, exc_type, _exc_val, _exc_tb) -> bool:
if exc_type is None:
raise RuntimeError('A `Skippable` context manager was entered, but a `skip_on_ignore` handler was never invoked.')
return exc_type is _SkipException # only mask a _SkipException, allow all others to raise
Skippable = _SkippableContextManager()
"""Context manager singleton required to enclose `ErrorHandler.handle` invocations when `skip_on_ignore` is `True`."""
class ErrorHandler:
"""
Provides a configurable error handler context manager for a specific list of exception types.
Unhandled errors leaving the context manager can be ignored, treated as warnings, or allowed to raise by setting `ErrorAction`.
"""
def __init__(self, action: ErrorAction) -> None:
self.action = action
@contextlib.contextmanager
def handle(self, *args: type[BaseException], skip_on_ignore: bool = False) -> t.Iterator[None]:
"""
Handle the specified exception(s) using the defined error action.
If `skip_on_ignore` is `True`, the body of the context manager will be skipped for `ErrorAction.IGNORE`.
Use of `skip_on_ignore` requires enclosure within the `Skippable` context manager.
"""
if not args:
raise ValueError('At least one exception type is required.')
if skip_on_ignore and self.action == ErrorAction.IGNORE:
raise _SkipException() # skipping ignored action
try:
yield
except args as ex:
match self.action:
case ErrorAction.WARNING:
display.error_as_warning(msg=None, exception=ex)
case ErrorAction.ERROR:
raise
case _: # ErrorAction.IGNORE
pass
if skip_on_ignore:
raise _SkipException() # completed skippable action, ensures the `Skippable` context was used
@classmethod
def from_config(cls, setting: str, variables: dict[str, t.Any] | None = None) -> t.Self:
"""Return an `ErrorHandler` instance configured using the specified Ansible config setting."""
return cls(ErrorAction.from_config(setting, variables=variables))
ansible_core-2.19.0b4/lib/ansible/_internal/_errors/_utils.py 0000644 0000000 0000000 00000027246 15010426755 022716 0 ustar 00root root from __future__ import annotations
import dataclasses
import itertools
import pathlib
import sys
import textwrap
import typing as t
from ansible.module_utils.common.messages import Detail, ErrorSummary
from ansible._internal._datatag._tags import Origin
from ansible.module_utils._internal import _ambient_context, _traceback
from ansible import errors
if t.TYPE_CHECKING:
from ansible.utils.display import Display
class RedactAnnotatedSourceContext(_ambient_context.AmbientContextBase):
"""
When active, this context will redact annotated source lines, showing only the origin.
"""
def _dedupe_and_concat_message_chain(message_parts: list[str]) -> str:
message_parts = list(reversed(message_parts))
message = message_parts.pop(0)
for message_part in message_parts:
# avoid duplicate messages where the cause was already concatenated to the exception message
if message_part.endswith(message):
message = message_part
else:
message = concat_message(message_part, message)
return message
def _collapse_error_details(error_details: t.Sequence[Detail]) -> list[Detail]:
"""
Return a potentially modified error chain, with redundant errors collapsed into previous error(s) in the chain.
This reduces the verbosity of messages by eliminating repetition when multiple errors in the chain share the same contextual information.
"""
previous_error = error_details[0]
previous_warnings: list[str] = []
collapsed_error_details: list[tuple[Detail, list[str]]] = [(previous_error, previous_warnings)]
for error in error_details[1:]:
details_present = error.formatted_source_context or error.help_text
details_changed = error.formatted_source_context != previous_error.formatted_source_context or error.help_text != previous_error.help_text
if details_present and details_changed:
previous_error = error
previous_warnings = []
collapsed_error_details.append((previous_error, previous_warnings))
else:
previous_warnings.append(error.msg)
final_error_details: list[Detail] = []
for error, messages in collapsed_error_details:
final_error_details.append(dataclasses.replace(error, msg=_dedupe_and_concat_message_chain([error.msg] + messages)))
return final_error_details
def _get_cause(exception: BaseException) -> BaseException | None:
# deprecated: description='remove support for orig_exc (deprecated in 2.23)' core_version='2.27'
if not isinstance(exception, errors.AnsibleError):
return exception.__cause__
if exception.__cause__:
if exception.orig_exc and exception.orig_exc is not exception.__cause__:
_get_display().warning(
msg=f"The `orig_exc` argument to `{type(exception).__name__}` was given, but differed from the cause given by `raise ... from`.",
)
return exception.__cause__
if exception.orig_exc:
# encourage the use of `raise ... from` before deprecating `orig_exc`
_get_display().warning(msg=f"The `orig_exc` argument to `{type(exception).__name__}` was given without using `raise ... from orig_exc`.")
return exception.orig_exc
return None
class _TemporaryDisplay:
# DTFIX-FUTURE: generalize this and hide it in the display module so all users of Display can benefit
@staticmethod
def warning(*args, **kwargs):
print(f'FALLBACK WARNING: {args} {kwargs}', file=sys.stderr)
@staticmethod
def deprecated(*args, **kwargs):
print(f'FALLBACK DEPRECATION: {args} {kwargs}', file=sys.stderr)
def _get_display() -> Display | _TemporaryDisplay:
try:
from ansible.utils.display import Display
except ImportError:
return _TemporaryDisplay()
return Display()
def _create_error_summary(exception: BaseException, event: _traceback.TracebackEvent | None = None) -> ErrorSummary:
from . import _captured # avoid circular import due to AnsibleError import
current_exception: BaseException | None = exception
error_details: list[Detail] = []
if event:
formatted_traceback = _traceback.maybe_extract_traceback(exception, event)
else:
formatted_traceback = None
while current_exception:
if isinstance(current_exception, errors.AnsibleError):
include_cause_message = current_exception._include_cause_message
edc = Detail(
msg=current_exception._original_message.strip(),
formatted_source_context=current_exception._formatted_source_context,
help_text=current_exception._help_text,
)
else:
include_cause_message = True
edc = Detail(
msg=str(current_exception).strip(),
)
error_details.append(edc)
if isinstance(current_exception, _captured.AnsibleCapturedError):
detail = current_exception.error_summary
error_details.extend(detail.details)
if formatted_traceback and detail.formatted_traceback:
formatted_traceback = (
f'{detail.formatted_traceback}\n'
f'The {current_exception.context} exception above was the direct cause of the following controller exception:\n\n'
f'{formatted_traceback}'
)
if not include_cause_message:
break
current_exception = _get_cause(current_exception)
return ErrorSummary(details=tuple(error_details), formatted_traceback=formatted_traceback)
def concat_message(left: str, right: str) -> str:
"""Normalize `left` by removing trailing punctuation and spaces before appending new punctuation and `right`."""
return f'{left.rstrip(". ")}: {right}'
def get_chained_message(exception: BaseException) -> str:
"""
Return the full chain of exception messages by concatenating the cause(s) until all are exhausted.
"""
error_summary = _create_error_summary(exception)
message_parts = [edc.msg for edc in error_summary.details]
return _dedupe_and_concat_message_chain(message_parts)
@dataclasses.dataclass(kw_only=True, frozen=True)
class SourceContext:
origin: Origin
annotated_source_lines: list[str]
target_line: str | None
def __str__(self) -> str:
msg_lines = [f'Origin: {self.origin}']
if self.annotated_source_lines:
msg_lines.append('')
msg_lines.extend(self.annotated_source_lines)
return '\n'.join(msg_lines)
@classmethod
def from_value(cls, value: t.Any) -> SourceContext | None:
"""Attempt to retrieve source and render a contextual indicator from the value's origin (if any)."""
if value is None:
return None
if isinstance(value, Origin):
origin = value
value = None
else:
origin = Origin.get_tag(value)
if RedactAnnotatedSourceContext.current(optional=True):
return cls.error('content redacted')
if origin and origin.path:
return cls.from_origin(origin)
# DTFIX-RELEASE: redaction context may not be sufficient to avoid secret disclosure without SensitiveData and other enhancements
if value is None:
truncated_value = None
annotated_source_lines = []
else:
# DTFIX-FUTURE: cleanup/share width
try:
value = str(value)
except Exception as ex:
value = f'<< context unavailable: {ex} >>'
truncated_value = textwrap.shorten(value, width=120)
annotated_source_lines = [truncated_value]
return SourceContext(
origin=origin or Origin.UNKNOWN,
annotated_source_lines=annotated_source_lines,
target_line=truncated_value,
)
@staticmethod
def error(message: str | None, origin: Origin | None = None) -> SourceContext:
return SourceContext(
origin=origin,
annotated_source_lines=[f'(source not shown: {message})'] if message else [],
target_line=None,
)
@classmethod
def from_origin(cls, origin: Origin) -> SourceContext:
"""Attempt to retrieve source and render a contextual indicator of an error location."""
from ansible.parsing.vault import is_encrypted # avoid circular import
# DTFIX-FUTURE: support referencing the column after the end of the target line, so we can indicate where a missing character (quote) needs to be added
# this is also useful for cases like end-of-stream reported by the YAML parser
# DTFIX-FUTURE: Implement line wrapping and match annotated line width to the terminal display width.
context_line_count: t.Final = 2
max_annotated_line_width: t.Final = 120
truncation_marker: t.Final = '...'
target_line_num = origin.line_num
if RedactAnnotatedSourceContext.current(optional=True):
return cls.error('content redacted', origin)
if not target_line_num or target_line_num < 1:
return cls.error(None, origin) # message omitted since lack of line number is obvious from pos
start_line_idx = max(0, (target_line_num - 1) - context_line_count) # if near start of file
target_col_num = origin.col_num
try:
with pathlib.Path(origin.path).open() as src:
first_line = src.readline()
lines = list(itertools.islice(itertools.chain((first_line,), src), start_line_idx, target_line_num))
except Exception as ex:
return cls.error(type(ex).__name__, origin)
if is_encrypted(first_line):
return cls.error('content encrypted', origin)
if len(lines) != target_line_num - start_line_idx:
return cls.error('file truncated', origin)
annotated_source_lines = []
line_label_width = len(str(target_line_num))
max_src_line_len = max_annotated_line_width - line_label_width - 1
usable_line_len = max_src_line_len
for line_num, line in enumerate(lines, start_line_idx + 1):
line = line.rstrip('\n') # universal newline default mode on `open` ensures we'll never see anything but \n
line = line.replace('\t', ' ') # mixed tab/space handling is intentionally disabled since we're both format and display config agnostic
if len(line) > max_src_line_len:
line = line[: max_src_line_len - len(truncation_marker)] + truncation_marker
usable_line_len = max_src_line_len - len(truncation_marker)
annotated_source_lines.append(f'{str(line_num).rjust(line_label_width)}{" " if line else ""}{line}')
if target_col_num and usable_line_len >= target_col_num >= 1:
column_marker = f'column {target_col_num}'
target_col_idx = target_col_num - 1
if target_col_idx + 2 + len(column_marker) > max_src_line_len:
column_marker = f'{" " * (target_col_idx - len(column_marker) - 1)}{column_marker} ^'
else:
column_marker = f'{" " * target_col_idx}^ {column_marker}'
column_marker = f'{" " * line_label_width} {column_marker}'
annotated_source_lines.append(column_marker)
elif target_col_num is None:
underline_length = len(annotated_source_lines[-1]) - line_label_width - 1
annotated_source_lines.append(f'{" " * line_label_width} {"^" * underline_length}')
return SourceContext(
origin=origin,
annotated_source_lines=annotated_source_lines,
target_line=lines[-1].rstrip('\n'), # universal newline default mode on `open` ensures we'll never see anything but \n
)
ansible_core-2.19.0b4/lib/ansible/_internal/_json/ 0000755 0000000 0000000 00000000000 15010426755 020467 5 ustar 00root root ansible_core-2.19.0b4/lib/ansible/_internal/_json/__init__.py 0000644 0000000 0000000 00000021171 15010426755 022602 0 ustar 00root root """Internal utilities for serialization and deserialization."""
# DTFIX-RELEASE: most of this isn't JSON specific, find a better home
from __future__ import annotations
import enum
import json
import typing as t
from ansible.errors import AnsibleVariableTypeError
from ansible.module_utils._internal._datatag import (
_ANSIBLE_ALLOWED_MAPPING_VAR_TYPES,
_ANSIBLE_ALLOWED_NON_SCALAR_COLLECTION_VAR_TYPES,
_ANSIBLE_ALLOWED_VAR_TYPES,
_AnsibleTaggedStr,
AnsibleTagHelper,
)
from ansible.module_utils._internal._json._profiles import _tagless
from ansible.parsing.vault import EncryptedString
from ansible._internal._datatag._tags import Origin, TrustedAsTemplate
from ansible._internal._templating import _transform
from ansible.module_utils import _internal
from ansible.module_utils._internal import _datatag
_T = t.TypeVar('_T')
_sentinel = object()
class HasCurrent(t.Protocol):
"""Utility protocol for mixin type safety."""
_current: t.Any
class StateTrackingMixIn(HasCurrent):
"""Mixin for use with `AnsibleVariableVisitor` to track current visitation context."""
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
self._stack: list[t.Any] = []
def __enter__(self) -> None:
self._stack.append(self._current)
def __exit__(self, *_args, **_kwargs) -> None:
self._stack.pop()
def _get_stack(self) -> list[t.Any]:
if not self._stack:
return []
return self._stack[1:] + [self._current]
class EncryptedStringBehavior(enum.Enum):
"""How `AnsibleVariableVisitor` will handle instances of `EncryptedString`."""
PRESERVE = enum.auto()
"""Preserves the unmodified `EncryptedString` instance."""
DECRYPT = enum.auto()
"""Replaces the value with its decrypted plaintext."""
REDACT = enum.auto()
"""Replaces the value with a placeholder string."""
FAIL = enum.auto()
"""Raises an `AnsibleVariableTypeError` error."""
class AnsibleVariableVisitor:
"""Utility visitor base class to recursively apply various behaviors and checks to variable object graphs."""
def __init__(
self,
*,
trusted_as_template: bool = False,
origin: Origin | None = None,
convert_mapping_to_dict: bool = False,
convert_sequence_to_list: bool = False,
convert_custom_scalars: bool = False,
convert_to_native_values: bool = False,
apply_transforms: bool = False,
encrypted_string_behavior: EncryptedStringBehavior = EncryptedStringBehavior.DECRYPT,
):
super().__init__() # supports StateTrackingMixIn
self.trusted_as_template = trusted_as_template
self.origin = origin
self.convert_mapping_to_dict = convert_mapping_to_dict
self.convert_sequence_to_list = convert_sequence_to_list
self.convert_custom_scalars = convert_custom_scalars
self.convert_to_native_values = convert_to_native_values
self.apply_transforms = apply_transforms
self.encrypted_string_behavior = encrypted_string_behavior
if apply_transforms:
from ansible._internal._templating import _engine
self._template_engine = _engine.TemplateEngine()
else:
self._template_engine = None
self._current: t.Any = None # supports StateTrackingMixIn
def __enter__(self) -> t.Any:
"""No-op context manager dispatcher (delegates to mixin behavior if present)."""
if func := getattr(super(), '__enter__', None):
func()
def __exit__(self, *args, **kwargs) -> t.Any:
"""No-op context manager dispatcher (delegates to mixin behavior if present)."""
if func := getattr(super(), '__exit__', None):
func(*args, **kwargs)
def visit(self, value: _T) -> _T:
"""
Enforces Ansible's variable type system restrictions before a var is accepted in inventory. Also, conditionally implements template trust
compatibility, depending on the plugin's declared understanding (or lack thereof). This always recursively copies inputs to fully isolate
inventory data from what the plugin provided, and prevent any later mutation.
"""
return self._visit(None, value)
def _early_visit(self, value, value_type) -> t.Any:
"""Overridable hook point to allow custom string handling in derived visitors."""
if value_type in (str, _AnsibleTaggedStr):
# apply compatibility behavior
if self.trusted_as_template:
result = TrustedAsTemplate().tag(value)
else:
result = value
else:
result = _sentinel
return result
def _visit(self, key: t.Any, value: _T) -> _T:
"""Internal implementation to recursively visit a data structure's contents."""
self._current = key # supports StateTrackingMixIn
value_type = type(value)
if self.apply_transforms and value_type in _transform._type_transform_mapping:
value = self._template_engine.transform(value)
value_type = type(value)
# DTFIX-RELEASE: need to handle native copy for keys too
if self.convert_to_native_values and isinstance(value, _datatag.AnsibleTaggedObject):
value = value._native_copy()
value_type = type(value)
result: _T
# DTFIX-RELEASE: the visitor is ignoring dict/mapping keys except for debugging and schema-aware checking, it should be doing type checks on keys
# keep in mind the allowed types for keys is a more restrictive set than for values (str and tagged str only, not EncryptedString)
# DTFIX-RELEASE: some type lists being consulted (the ones from datatag) are probably too permissive, and perhaps should not be dynamic
if (result := self._early_visit(value, value_type)) is not _sentinel:
pass
# DTFIX-RELEASE: de-duplicate and optimize; extract inline generator expressions and fallback function or mapping for native type calculation?
elif value_type in _ANSIBLE_ALLOWED_MAPPING_VAR_TYPES: # check mappings first, because they're also collections
with self: # supports StateTrackingMixIn
result = AnsibleTagHelper.tag_copy(value, ((k, self._visit(k, v)) for k, v in value.items()), value_type=value_type)
elif value_type in _ANSIBLE_ALLOWED_NON_SCALAR_COLLECTION_VAR_TYPES:
with self: # supports StateTrackingMixIn
result = AnsibleTagHelper.tag_copy(value, (self._visit(k, v) for k, v in enumerate(t.cast(t.Iterable, value))), value_type=value_type)
elif self.encrypted_string_behavior != EncryptedStringBehavior.FAIL and isinstance(value, EncryptedString):
match self.encrypted_string_behavior:
case EncryptedStringBehavior.REDACT:
result = "" # type: ignore[assignment]
case EncryptedStringBehavior.PRESERVE:
result = value # type: ignore[assignment]
case EncryptedStringBehavior.DECRYPT:
result = str(value) # type: ignore[assignment]
elif self.convert_mapping_to_dict and _internal.is_intermediate_mapping(value):
with self: # supports StateTrackingMixIn
result = {k: self._visit(k, v) for k, v in value.items()} # type: ignore[assignment]
elif self.convert_sequence_to_list and _internal.is_intermediate_iterable(value):
with self: # supports StateTrackingMixIn
result = [self._visit(k, v) for k, v in enumerate(t.cast(t.Iterable, value))] # type: ignore[assignment]
elif self.convert_custom_scalars and isinstance(value, str):
result = str(value) # type: ignore[assignment]
elif self.convert_custom_scalars and isinstance(value, float):
result = float(value) # type: ignore[assignment]
elif self.convert_custom_scalars and isinstance(value, int) and not isinstance(value, bool):
result = int(value) # type: ignore[assignment]
else:
if value_type not in _ANSIBLE_ALLOWED_VAR_TYPES:
raise AnsibleVariableTypeError.from_value(obj=value)
# supported scalar type that requires no special handling, just return as-is
result = value
if self.origin and not Origin.is_tagged_on(result):
# apply shared instance default origin tag
result = self.origin.tag(result)
return result
def json_dumps_formatted(value: object) -> str:
"""Return a JSON dump of `value` with formatting and keys sorted."""
return json.dumps(value, cls=_tagless.Encoder, sort_keys=True, indent=4)
ansible_core-2.19.0b4/lib/ansible/_internal/_json/_legacy_encoder.py 0000644 0000000 0000000 00000003156 15010426755 024150 0 ustar 00root root from __future__ import annotations as _annotations
import typing as _t
from ansible.module_utils._internal._json import _profiles
from ansible._internal._json._profiles import _legacy
from ansible.parsing import vault as _vault
class LegacyControllerJSONEncoder(_legacy.Encoder):
"""Compatibility wrapper over `legacy` profile JSON encoder to support trust stripping and vault value plaintext conversion."""
def __init__(self, preprocess_unsafe: bool = False, vault_to_text: bool = False, _decode_bytes: bool = False, **kwargs) -> None:
self._preprocess_unsafe = preprocess_unsafe
self._vault_to_text = vault_to_text
self._decode_bytes = _decode_bytes
super().__init__(**kwargs)
def default(self, o: _t.Any) -> _t.Any:
"""Hooked default that can conditionally bypass base encoder behavior based on this instance's config."""
if type(o) is _profiles._WrappedValue: # pylint: disable=unidiomatic-typecheck
o = o.wrapped
if not self._preprocess_unsafe and type(o) is _legacy._Untrusted: # pylint: disable=unidiomatic-typecheck
return o.value # if not emitting unsafe markers, bypass custom unsafe serialization and just return the raw value
if self._vault_to_text and type(o) is _vault.EncryptedString: # pylint: disable=unidiomatic-typecheck
return str(o) # decrypt and return the plaintext (or fail trying)
if self._decode_bytes and isinstance(o, bytes):
return o.decode(errors='surrogateescape') # backward compatibility with `ansible.module_utils.basic.jsonify`
return super().default(o)
ansible_core-2.19.0b4/lib/ansible/_internal/_json/_profiles/ 0000755 0000000 0000000 00000000000 15010426755 022451 5 ustar 00root root ansible_core-2.19.0b4/lib/ansible/_internal/_json/_profiles/__init__.py 0000644 0000000 0000000 00000000000 15010426755 024550 0 ustar 00root root ansible_core-2.19.0b4/lib/ansible/_internal/_json/_profiles/_cache_persistence.py 0000644 0000000 0000000 00000003431 15010426755 026632 0 ustar 00root root from __future__ import annotations
import datetime as _datetime
from ansible.module_utils._internal import _datatag
from ansible.module_utils._internal._json import _profiles
from ansible.parsing import vault as _vault
from ansible._internal._datatag import _tags
class _Profile(_profiles._JSONSerializationProfile):
"""Profile for external cache persistence of inventory/fact data that preserves most tags."""
serialize_map = {}
schema_id = 1
@classmethod
def post_init(cls, **kwargs):
cls.allowed_ansible_serializable_types = (
_profiles._common_module_types
| _profiles._common_module_response_types
| {
_datatag._AnsibleTaggedDate,
_datatag._AnsibleTaggedTime,
_datatag._AnsibleTaggedDateTime,
_datatag._AnsibleTaggedStr,
_datatag._AnsibleTaggedInt,
_datatag._AnsibleTaggedFloat,
_datatag._AnsibleTaggedList,
_datatag._AnsibleTaggedSet,
_datatag._AnsibleTaggedTuple,
_datatag._AnsibleTaggedDict,
_tags.SourceWasEncrypted,
_tags.Origin,
_tags.TrustedAsTemplate,
_vault.EncryptedString,
_vault.VaultedValue,
}
)
cls.serialize_map = {
set: cls.serialize_as_list,
tuple: cls.serialize_as_list,
_datetime.date: _datatag.AnsibleSerializableDate,
_datetime.time: _datatag.AnsibleSerializableTime,
_datetime.datetime: _datatag.AnsibleSerializableDateTime,
}
class Encoder(_profiles.AnsibleProfileJSONEncoder):
_profile = _Profile
class Decoder(_profiles.AnsibleProfileJSONDecoder):
_profile = _Profile
ansible_core-2.19.0b4/lib/ansible/_internal/_json/_profiles/_inventory_legacy.py 0000644 0000000 0000000 00000002102 15010426755 026536 0 ustar 00root root """
Backwards compatibility profile for serialization for persisted ansible-inventory output.
Behavior is equivalent to pre 2.18 `AnsibleJSONEncoder` with vault_to_text=True.
"""
from __future__ import annotations
from ... import _json
from . import _legacy
class _InventoryVariableVisitor(_legacy._LegacyVariableVisitor, _json.StateTrackingMixIn):
"""State-tracking visitor implementation that only applies trust to `_meta.hostvars` and `vars` inventory values."""
# DTFIX-RELEASE: does the variable visitor need to support conversion of sequence/mapping for inventory?
@property
def _allow_trust(self) -> bool:
stack = self._get_stack()
if len(stack) >= 4 and stack[:2] == ['_meta', 'hostvars']:
return True
if len(stack) >= 3 and stack[1] == 'vars':
return True
return False
class _Profile(_legacy._Profile):
visitor_type = _InventoryVariableVisitor
encode_strings_as_utf8 = True
class Encoder(_legacy.Encoder):
_profile = _Profile
class Decoder(_legacy.Decoder):
_profile = _Profile
ansible_core-2.19.0b4/lib/ansible/_internal/_json/_profiles/_legacy.py 0000644 0000000 0000000 00000017331 15010426755 024433 0 ustar 00root root """
Backwards compatibility profile for serialization other than inventory (which should use inventory_legacy for backward-compatible trust behavior).
Behavior is equivalent to pre 2.18 `AnsibleJSONEncoder` with vault_to_text=True.
"""
from __future__ import annotations as _annotations
import datetime as _datetime
import typing as _t
from ansible._internal import _json
from ansible._internal._datatag import _tags
from ansible.module_utils._internal import _datatag
from ansible.module_utils._internal._json import _profiles
from ansible.parsing import vault as _vault
class _Untrusted:
"""
Temporarily wraps strings which are not trusted for templating.
Used before serialization of strings not tagged TrustedAsTemplate when trust inversion is enabled and trust is allowed in the string's context.
Used during deserialization of `__ansible_unsafe` strings to indicate they should not be tagged TrustedAsTemplate.
"""
__slots__ = ('value',)
def __init__(self, value: str) -> None:
self.value = value
class _LegacyVariableVisitor(_json.AnsibleVariableVisitor):
"""Variable visitor that supports optional trust inversion for legacy serialization."""
def __init__(
self,
*,
trusted_as_template: bool = False,
invert_trust: bool = False,
origin: _tags.Origin | None = None,
convert_mapping_to_dict: bool = False,
convert_sequence_to_list: bool = False,
convert_custom_scalars: bool = False,
):
super().__init__(
trusted_as_template=trusted_as_template,
origin=origin,
convert_mapping_to_dict=convert_mapping_to_dict,
convert_sequence_to_list=convert_sequence_to_list,
convert_custom_scalars=convert_custom_scalars,
encrypted_string_behavior=_json.EncryptedStringBehavior.PRESERVE,
)
self.invert_trust = invert_trust
if trusted_as_template and invert_trust:
raise ValueError('trusted_as_template is mutually exclusive with invert_trust')
@property
def _allow_trust(self) -> bool:
"""
This profile supports trust application in all contexts.
Derived implementations can override this behavior for application-dependent/schema-aware trust.
"""
return True
def _early_visit(self, value, value_type) -> _t.Any:
"""Similar to base implementation, but supports an intermediate wrapper for trust inversion."""
if value_type in (str, _datatag._AnsibleTaggedStr):
# apply compatibility behavior
if self.trusted_as_template and self._allow_trust:
result = _tags.TrustedAsTemplate().tag(value)
elif self.invert_trust and not _tags.TrustedAsTemplate.is_tagged_on(value) and self._allow_trust:
result = _Untrusted(value)
else:
result = value
elif value_type is _Untrusted:
result = value.value
else:
result = _json._sentinel
return result
class _Profile(_profiles._JSONSerializationProfile["Encoder", "Decoder"]):
visitor_type = _LegacyVariableVisitor
@classmethod
def serialize_untrusted(cls, value: _Untrusted) -> dict[str, str] | str:
return dict(
__ansible_unsafe=_datatag.AnsibleTagHelper.untag(value.value),
)
@classmethod
def serialize_tagged_str(cls, value: _datatag.AnsibleTaggedObject) -> _t.Any:
if ciphertext := _vault.VaultHelper.get_ciphertext(value, with_tags=False):
return dict(
__ansible_vault=ciphertext,
)
return _datatag.AnsibleTagHelper.untag(value)
@classmethod
def deserialize_unsafe(cls, value: dict[str, _t.Any]) -> _Untrusted:
ansible_unsafe = value['__ansible_unsafe']
if type(ansible_unsafe) is not str: # pylint: disable=unidiomatic-typecheck
raise TypeError(f"__ansible_unsafe is {type(ansible_unsafe)} not {str}")
return _Untrusted(ansible_unsafe)
@classmethod
def deserialize_vault(cls, value: dict[str, _t.Any]) -> _vault.EncryptedString:
ansible_vault = value['__ansible_vault']
if type(ansible_vault) is not str: # pylint: disable=unidiomatic-typecheck
raise TypeError(f"__ansible_vault is {type(ansible_vault)} not {str}")
encrypted_string = _vault.EncryptedString(ciphertext=ansible_vault)
return encrypted_string
@classmethod
def serialize_encrypted_string(cls, value: _vault.EncryptedString) -> dict[str, str]:
return dict(
__ansible_vault=_vault.VaultHelper.get_ciphertext(value, with_tags=False),
)
@classmethod
def post_init(cls) -> None:
cls.serialize_map = {
set: cls.serialize_as_list,
tuple: cls.serialize_as_list,
_datetime.date: cls.serialize_as_isoformat, # existing devel behavior
_datetime.time: cls.serialize_as_isoformat, # always failed pre-2.18, so okay to include for consistency
_datetime.datetime: cls.serialize_as_isoformat, # existing devel behavior
_datatag._AnsibleTaggedDate: cls.discard_tags,
_datatag._AnsibleTaggedTime: cls.discard_tags,
_datatag._AnsibleTaggedDateTime: cls.discard_tags,
_vault.EncryptedString: cls.serialize_encrypted_string,
_datatag._AnsibleTaggedStr: cls.serialize_tagged_str, # for VaultedValue tagged str
_datatag._AnsibleTaggedInt: cls.discard_tags,
_datatag._AnsibleTaggedFloat: cls.discard_tags,
_datatag._AnsibleTaggedList: cls.discard_tags,
_datatag._AnsibleTaggedSet: cls.discard_tags,
_datatag._AnsibleTaggedTuple: cls.discard_tags,
_datatag._AnsibleTaggedDict: cls.discard_tags,
_Untrusted: cls.serialize_untrusted, # equivalent to AnsibleJSONEncoder(preprocess_unsafe=True) in devel
}
cls.deserialize_map = {
'__ansible_unsafe': cls.deserialize_unsafe,
'__ansible_vault': cls.deserialize_vault,
}
@classmethod
def pre_serialize(cls, encoder: Encoder, o: _t.Any) -> _t.Any:
# DTFIX-RELEASE: these conversion args probably aren't needed
avv = cls.visitor_type(invert_trust=True, convert_mapping_to_dict=True, convert_sequence_to_list=True, convert_custom_scalars=True)
return avv.visit(o)
@classmethod
def post_deserialize(cls, decoder: Decoder, o: _t.Any) -> _t.Any:
avv = cls.visitor_type(trusted_as_template=decoder._trusted_as_template, origin=decoder._origin)
return avv.visit(o)
@classmethod
def handle_key(cls, k: _t.Any) -> _t.Any:
if isinstance(k, str):
return k
# DTFIX-RELEASE: decide if this is a deprecation warning, error, or what?
# Non-string variable names have been disallowed by set_fact and other things since at least 2021.
# DTFIX-RELEASE: document why this behavior is here, also verify the legacy tagless use case doesn't need this same behavior
return str(k)
class Encoder(_profiles.AnsibleProfileJSONEncoder):
_profile = _Profile
class Decoder(_profiles.AnsibleProfileJSONDecoder):
_profile = _Profile
def __init__(self, **kwargs) -> None:
super().__init__(**kwargs)
# NB: these can only be sampled properly when loading strings, eg, `json.loads`; the global `json.load` function does not expose the file-like to us
self._origin: _tags.Origin | None = None
self._trusted_as_template: bool = False
def raw_decode(self, s: str, idx: int = 0) -> tuple[_t.Any, int]:
self._origin = _tags.Origin.get_tag(s)
self._trusted_as_template = _tags.TrustedAsTemplate.is_tagged_on(s)
return super().raw_decode(s, idx)
ansible_core-2.19.0b4/lib/ansible/_internal/_locking.py 0000644 0000000 0000000 00000001235 15010426755 021517 0 ustar 00root root from __future__ import annotations
import contextlib
import fcntl
import typing as t
@contextlib.contextmanager
def named_mutex(path: str) -> t.Iterator[None]:
"""
Lightweight context manager wrapper over `fcntl.flock` to provide IPC locking via a shared filename.
Entering the context manager blocks until the lock is acquired.
The lock file will be created automatically, but creation of the parent directory and deletion of the lockfile are the caller's responsibility.
"""
with open(path, 'a') as file:
fcntl.flock(file, fcntl.LOCK_EX)
try:
yield
finally:
fcntl.flock(file, fcntl.LOCK_UN)
ansible_core-2.19.0b4/lib/ansible/_internal/_plugins/ 0000755 0000000 0000000 00000000000 15010426755 021177 5 ustar 00root root ansible_core-2.19.0b4/lib/ansible/_internal/_plugins/__init__.py 0000644 0000000 0000000 00000000000 15010426755 023276 0 ustar 00root root ansible_core-2.19.0b4/lib/ansible/_internal/_plugins/_cache.py 0000644 0000000 0000000 00000003705 15010426755 022760 0 ustar 00root root from __future__ import annotations
import functools
import json
import json.encoder
import json.decoder
import typing as t
from .._wrapt import ObjectProxy
from .._json._profiles import _cache_persistence
class PluginInterposer(ObjectProxy):
"""Proxies a Cache plugin instance to implement transparent encapsulation of serialized Ansible internal data types."""
_PAYLOAD_KEY = '__payload__'
"""The key used to store the serialized payload."""
def get(self, key: str) -> dict[str, object]:
return self._decode(self.__wrapped__.get(self._get_key(key)))
def set(self, key: str, value: dict[str, object]) -> None:
self.__wrapped__.set(self._get_key(key), self._encode(value))
def keys(self) -> t.Sequence[str]:
return [k for k in (self._restore_key(k) for k in self.__wrapped__.keys()) if k is not None]
def contains(self, key: t.Any) -> bool:
return self.__wrapped__.contains(self._get_key(key))
def delete(self, key: str) -> None:
self.__wrapped__.delete(self._get_key(key))
@classmethod
def _restore_key(cls, wrapped_key: str) -> str | None:
prefix = cls._get_wrapped_key_prefix()
if not wrapped_key.startswith(prefix):
return None
return wrapped_key[len(prefix) :]
@classmethod
@functools.cache
def _get_wrapped_key_prefix(cls) -> str:
return f's{_cache_persistence._Profile.schema_id}_'
@classmethod
def _get_key(cls, key: str) -> str:
"""Augment the supplied key with a schema identifier to allow for side-by-side caching across incompatible schemas."""
return f'{cls._get_wrapped_key_prefix()}{key}'
def _encode(self, value: dict[str, object]) -> dict[str, object]:
return {self._PAYLOAD_KEY: json.dumps(value, cls=_cache_persistence.Encoder)}
def _decode(self, value: dict[str, t.Any]) -> dict[str, object]:
return json.loads(value[self._PAYLOAD_KEY], cls=_cache_persistence.Decoder)
ansible_core-2.19.0b4/lib/ansible/_internal/_task.py 0000644 0000000 0000000 00000006335 15010426755 021041 0 ustar 00root root from __future__ import annotations
import dataclasses
import typing as t
from collections import abc as c
from ansible import constants
from ansible._internal._templating import _engine
from ansible._internal._templating._chain_templar import ChainTemplar
from ansible.errors import AnsibleError
from ansible.module_utils._internal._ambient_context import AmbientContextBase
from ansible.module_utils.datatag import native_type_name
from ansible.parsing import vault as _vault
from ansible.utils.display import Display
if t.TYPE_CHECKING:
from ansible.playbook.task import Task
@dataclasses.dataclass
class TaskContext(AmbientContextBase):
"""Ambient context that wraps task execution on workers. It provides access to the currently executing task."""
task: Task
TaskArgsFinalizerCallback = t.Callable[[str, t.Any, _engine.TemplateEngine, t.Any], t.Any]
"""Type alias for the shape of the `ActionBase.finalize_task_arg` method."""
class TaskArgsChainTemplar(ChainTemplar):
"""
A ChainTemplar that carries a user-provided context object, optionally provided by `ActionBase.get_finalize_task_args_context`.
TaskArgsFinalizer provides the context to each `ActionBase.finalize_task_arg` call to allow for more complex/stateful customization.
"""
def __init__(self, *sources: c.Mapping, templar: _engine.TemplateEngine, callback: TaskArgsFinalizerCallback, context: t.Any) -> None:
super().__init__(*sources, templar=templar)
self.callback = callback
self.context = context
def template(self, key: t.Any, value: t.Any) -> t.Any:
return self.callback(key, value, self.templar, self.context)
class TaskArgsFinalizer:
"""Invoked during task args finalization; allows actions to override default arg processing (e.g., templating)."""
def __init__(self, *args: c.Mapping[str, t.Any] | str | None, templar: _engine.TemplateEngine) -> None:
self._args_layers = [arg for arg in args if arg is not None]
self._templar = templar
def finalize(self, callback: TaskArgsFinalizerCallback, context: t.Any) -> dict[str, t.Any]:
resolved_layers: list[c.Mapping[str, t.Any]] = []
for layer in self._args_layers:
if isinstance(layer, (str, _vault.EncryptedString)): # EncryptedString can hide a template
if constants.config.get_config_value('INJECT_FACTS_AS_VARS'):
Display().warning(
"Using a template for task args is unsafe in some situations "
"(see https://docs.ansible.com/ansible/devel/reference_appendices/faq.html#argsplat-unsafe).",
obj=layer,
)
resolved_layer = self._templar.resolve_to_container(layer, options=_engine.TemplateOptions(value_for_omit={}))
else:
resolved_layer = layer
if not isinstance(resolved_layer, dict):
raise AnsibleError(f'Task args must resolve to a {native_type_name(dict)!r} not {native_type_name(resolved_layer)!r}.', obj=layer)
resolved_layers.append(resolved_layer)
ct = TaskArgsChainTemplar(*reversed(resolved_layers), templar=self._templar, callback=callback, context=context)
return ct.as_dict()
ansible_core-2.19.0b4/lib/ansible/_internal/_templating/ 0000755 0000000 0000000 00000000000 15010426755 021662 5 ustar 00root root ansible_core-2.19.0b4/lib/ansible/_internal/_templating/__init__.py 0000644 0000000 0000000 00000000735 15010426755 024000 0 ustar 00root root from __future__ import annotations
from jinja2 import __version__ as _jinja2_version
# DTFIX-FUTURE: sanity test to ensure this doesn't drift from requirements
_MINIMUM_JINJA_VERSION = (3, 1)
_CURRENT_JINJA_VERSION = tuple(map(int, _jinja2_version.split('.', maxsplit=2)[:2]))
if _CURRENT_JINJA_VERSION < _MINIMUM_JINJA_VERSION:
raise RuntimeError(f'Jinja version {".".join(map(str, _MINIMUM_JINJA_VERSION))} or higher is required (current version {_jinja2_version}).')
ansible_core-2.19.0b4/lib/ansible/_internal/_templating/_access.py 0000644 0000000 0000000 00000006613 15010426755 023642 0 ustar 00root root from __future__ import annotations
import abc
import typing as t
from contextvars import ContextVar
from ansible.module_utils._internal._datatag import AnsibleTagHelper
class NotifiableAccessContextBase(metaclass=abc.ABCMeta):
"""Base class for a context manager that, when active, receives notification of managed access for types/tags in which it has registered an interest."""
_type_interest: t.FrozenSet[type] = frozenset()
"""Set of types (including tag types) for which this context will be notified upon access."""
_mask: t.ClassVar[bool] = False
"""When true, only the innermost (most recently created) context of this type will be notified."""
def __enter__(self):
# noinspection PyProtectedMember
AnsibleAccessContext.current()._register_interest(self)
return self
def __exit__(self, exc_type, exc_val, exc_tb) -> None:
# noinspection PyProtectedMember
AnsibleAccessContext.current()._unregister_interest(self)
return None
@abc.abstractmethod
def _notify(self, o: t.Any) -> t.Any:
"""Derived classes implement custom notification behavior when a registered type or tag is accessed."""
class AnsibleAccessContext:
"""
Broker object for managed access registration and notification.
Each thread or other logical callstack has a dedicated `AnsibleAccessContext` object with which `NotifiableAccessContext` objects can register interest.
When a managed access occurs on an object, each active `NotifiableAccessContext` within the current callstack that has registered interest in that
object's type or a tag present on it will be notified.
"""
_contextvar: t.ClassVar[ContextVar[AnsibleAccessContext]] = ContextVar('AnsibleAccessContext')
@staticmethod
def current() -> AnsibleAccessContext:
"""Creates or retrieves an `AnsibleAccessContext` for the current logical callstack."""
try:
ctx: AnsibleAccessContext = AnsibleAccessContext._contextvar.get()
except LookupError:
# didn't exist; create it
ctx = AnsibleAccessContext()
AnsibleAccessContext._contextvar.set(ctx) # we ignore the token, since this should live for the life of the thread/async ctx
return ctx
def __init__(self) -> None:
self._notify_contexts: list[NotifiableAccessContextBase] = []
def _register_interest(self, context: NotifiableAccessContextBase) -> None:
self._notify_contexts.append(context)
def _unregister_interest(self, context: NotifiableAccessContextBase) -> None:
ctx = self._notify_contexts.pop()
if ctx is not context:
raise RuntimeError(f'Out-of-order context deactivation detected. Found {ctx} instead of {context}.')
def access(self, value: t.Any) -> None:
"""Notify all contexts which have registered interest in the given value that it is being accessed."""
if not self._notify_contexts:
return
value_types = AnsibleTagHelper.tag_types(value) | frozenset((type(value),))
masked: set[type] = set()
for ctx in reversed(self._notify_contexts):
if ctx._mask:
if (ctx_type := type(ctx)) in masked:
continue
masked.add(ctx_type)
# noinspection PyProtectedMember
if ctx._type_interest.intersection(value_types):
ctx._notify(value)
ansible_core-2.19.0b4/lib/ansible/_internal/_templating/_chain_templar.py 0000644 0000000 0000000 00000004320 15010426755 025200 0 ustar 00root root from __future__ import annotations
import collections.abc as c
import itertools
import typing as t
from ansible.errors import AnsibleValueOmittedError, AnsibleError
from ._engine import TemplateEngine
class ChainTemplar:
"""A basic variable layering mechanism that supports templating and obliteration of `omit` values."""
def __init__(self, *sources: c.Mapping, templar: TemplateEngine) -> None:
self.sources = sources
self.templar = templar
def template(self, key: t.Any, value: t.Any) -> t.Any:
"""
Render the given value using the templar.
Intended to be overridden by subclasses.
"""
return self.templar.template(value)
def get(self, key: t.Any) -> t.Any:
"""Get the value for the given key, templating the result before returning it."""
for source in self.sources:
if key not in source:
continue
value = source[key]
try:
return self.template(key, value)
except AnsibleValueOmittedError:
break # omit == obliterate - matches historical behavior where dict layers were squashed before templating was applied
except Exception as ex:
raise AnsibleError(f'Error while resolving value for {key!r}.', obj=value) from ex
raise KeyError(key)
def keys(self) -> t.Iterable[t.Any]:
"""
Returns a sorted iterable of all keys present in all source layers, without templating associated values.
Values that resolve to `omit` are thus included.
"""
return sorted(set(itertools.chain.from_iterable(self.sources)))
def items(self) -> t.Iterable[t.Tuple[t.Any, t.Any]]:
"""
Returns a sorted iterable of (key, templated value) tuples.
Any tuple where the templated value resolves to `omit` will not be included in the result.
"""
for key in self.keys():
try:
yield key, self.get(key)
except KeyError:
pass
def as_dict(self) -> dict[t.Any, t.Any]:
"""Returns a dict representing all layers, squashed and templated, with `omit` values dropped."""
return dict(self.items())
ansible_core-2.19.0b4/lib/ansible/_internal/_templating/_datatag.py 0000644 0000000 0000000 00000007367 15010426755 024015 0 ustar 00root root from __future__ import annotations
import contextlib as _contextlib
import dataclasses
import typing as t
from ansible.module_utils._internal._datatag import AnsibleSingletonTagBase, _tag_dataclass_kwargs
from ansible.module_utils._internal._datatag._tags import Deprecated
from ansible._internal._datatag._tags import Origin
from ansible.utils.display import Display
from ._access import NotifiableAccessContextBase
from ._utils import TemplateContext
display = Display()
@dataclasses.dataclass(**_tag_dataclass_kwargs)
class _JinjaConstTemplate(AnsibleSingletonTagBase):
# deprecated: description='embedded Jinja constant string template support' core_version='2.23'
pass
@dataclasses.dataclass(frozen=True, kw_only=True, slots=True)
class _TrippedDeprecationInfo:
template: str
deprecated: Deprecated
class DeprecatedAccessAuditContext(NotifiableAccessContextBase):
"""When active, captures metadata about managed accesses to `Deprecated` tagged objects."""
_type_interest = frozenset([Deprecated])
@classmethod
def when(cls, condition: bool, /) -> t.Self | _contextlib.nullcontext:
"""Returns a new instance if `condition` is True (usually `TemplateContext.is_top_level`), otherwise a `nullcontext` instance."""
if condition:
return cls()
return _contextlib.nullcontext()
def __init__(self) -> None:
self._tripped_deprecation_info: dict[int, _TrippedDeprecationInfo] = {}
def __exit__(self, exc_type, exc_val, exc_tb) -> None:
result = super().__exit__(exc_type, exc_val, exc_tb)
for item in self._tripped_deprecation_info.values():
if Origin.is_tagged_on(item.template):
msg = item.deprecated.msg
else:
# without an origin, we need to include what context we do have (the template)
msg = f'While processing {item.template!r}: {item.deprecated.msg}'
display._deprecated_with_plugin_info(
msg=msg,
help_text=item.deprecated.help_text,
version=item.deprecated.version,
date=item.deprecated.date,
obj=item.template,
deprecator=item.deprecated.deprecator,
)
return result
def _notify(self, o: t.Any) -> None:
deprecated = Deprecated.get_required_tag(o)
deprecated_key = id(deprecated)
if deprecated_key in self._tripped_deprecation_info:
return # record only the first access for each deprecated tag in a given context
template_ctx = TemplateContext.current(optional=True)
template = template_ctx.template_value if template_ctx else None
# when the current template input is a container, provide a descriptive string with origin propagated (if possible)
if not isinstance(template, str):
# DTFIX-FUTURE: ascend the template stack to try and find the nearest string source template
origin = Origin.get_tag(template)
# DTFIX-RELEASE: this should probably use a synthesized description value on the tag
# it is reachable from the data_tagging_controller test: ../playbook_output_validator/filter.py actual_stdout.txt actual_stderr.txt
# -[DEPRECATION WARNING]: `something_old` is deprecated, don't use it! This feature will be removed in version 1.2.3.
# +[DEPRECATION WARNING]: While processing '<>': `something_old` is deprecated, don't use it! This feature will be removed in ...
template = '<>'
if origin:
origin.tag(template)
self._tripped_deprecation_info[deprecated_key] = _TrippedDeprecationInfo(
template=template,
deprecated=deprecated,
)
ansible_core-2.19.0b4/lib/ansible/_internal/_templating/_engine.py 0000644 0000000 0000000 00000067077 15010426755 023661 0 ustar 00root root # (c) 2012-2014, Michael DeHaan
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import annotations
import copy
import dataclasses
import enum
import textwrap
import typing as t
import collections.abc as c
import re
from collections import ChainMap
from ansible.errors import (
AnsibleError,
AnsibleValueOmittedError,
AnsibleUndefinedVariable,
AnsibleTemplateSyntaxError,
AnsibleBrokenConditionalError,
AnsibleTemplateTransformLimitError,
TemplateTrustCheckFailedError,
)
from ansible.module_utils._internal._datatag import AnsibleTaggedObject, NotTaggableError, AnsibleTagHelper
from ansible._internal._errors._handler import Skippable
from ansible._internal._datatag._tags import Origin, TrustedAsTemplate
from ansible.utils.display import Display
from ansible.utils.vars import validate_variable_name
from ansible.parsing.dataloader import DataLoader
from ._datatag import DeprecatedAccessAuditContext
from ._jinja_bits import (
AnsibleTemplate,
_TemplateCompileContext,
TemplateOverrides,
AnsibleEnvironment,
defer_template_error,
create_template_error,
is_possibly_template,
is_possibly_all_template,
AnsibleTemplateExpression,
_finalize_template_result,
FinalizeMode,
)
from ._jinja_common import _TemplateConfig, MarkerError, ExceptionMarker
from ._lazy_containers import _AnsibleLazyTemplateMixin
from ._marker_behaviors import MarkerBehavior, FAIL_ON_UNDEFINED
from ._transform import _type_transform_mapping
from ._utils import Omit, TemplateContext, IGNORE_SCALAR_VAR_TYPES, LazyOptions
from ...module_utils.datatag import native_type_name
_display = Display()
_shared_empty_unmask_type_names: frozenset[str] = frozenset()
TRANSFORM_CHAIN_LIMIT: int = 10
"""Arbitrary limit for chained transforms to prevent cycles; an exception will be raised if exceeded."""
class TemplateMode(enum.Enum):
# DTFIX-FUTURE: this enum ideally wouldn't exist - revisit/rename before making public
DEFAULT = enum.auto()
STOP_ON_TEMPLATE = enum.auto()
STOP_ON_CONTAINER = enum.auto()
ALWAYS_FINALIZE = enum.auto()
@dataclasses.dataclass(kw_only=True, slots=True, frozen=True)
class TemplateOptions:
DEFAULT: t.ClassVar[t.Self]
value_for_omit: object = Omit
escape_backslashes: bool = True
preserve_trailing_newlines: bool = True
# DTFIX-RELEASE: these aren't really overrides anymore, rename the dataclass and this field
# also mention in docstring this has no effect unless used to template a string
overrides: TemplateOverrides = TemplateOverrides.DEFAULT
TemplateOptions.DEFAULT = TemplateOptions()
class TemplateEncountered(Exception):
pass
class TemplateEngine:
"""
The main class for templating, with the main entry-point of template().
"""
_sentinel = object()
def __init__(
self,
loader: DataLoader | None = None,
variables: dict[str, t.Any] | ChainMap[str, t.Any] | None = None,
variables_factory: t.Callable[[], dict[str, t.Any] | ChainMap[str, t.Any]] | None = None,
marker_behavior: MarkerBehavior | None = None,
):
self._loader = loader
self._variables = variables
self._variables_factory = variables_factory
self._environment: AnsibleEnvironment | None = None
# inherit marker behavior from the active template context's templar unless otherwise specified
if not marker_behavior:
if template_ctx := TemplateContext.current(optional=True):
marker_behavior = template_ctx.templar.marker_behavior
else:
marker_behavior = FAIL_ON_UNDEFINED
self._marker_behavior = marker_behavior
def copy(self) -> t.Self:
new_engine = copy.copy(self)
new_engine._environment = None
return new_engine
def extend(self, marker_behavior: MarkerBehavior | None = None) -> t.Self:
# DTFIX-RELEASE: bikeshed name, supported features
new_templar = type(self)(
loader=self._loader,
variables=self._variables,
variables_factory=self._variables_factory,
marker_behavior=marker_behavior or self._marker_behavior,
)
if self._environment:
new_templar._environment = self._environment
return new_templar
@property
def marker_behavior(self) -> MarkerBehavior:
return self._marker_behavior
@property
def basedir(self) -> str:
"""The basedir from DataLoader."""
return self._loader.get_basedir() if self._loader else '.'
@property
def environment(self) -> AnsibleEnvironment:
if not self._environment:
self._environment = AnsibleEnvironment(ansible_basedir=self.basedir)
return self._environment
def _create_overlay(self, template: str, overrides: TemplateOverrides) -> tuple[str, AnsibleEnvironment]:
try:
template, overrides = overrides._extract_template_overrides(template)
except Exception as ex:
raise AnsibleTemplateSyntaxError("Syntax error in template.", obj=template) from ex
env = self.environment
if overrides is not TemplateOverrides.DEFAULT and (overlay_kwargs := overrides.overlay_kwargs()):
env = t.cast(AnsibleEnvironment, env.overlay(**overlay_kwargs))
return template, env
@staticmethod
def _count_newlines_from_end(in_str):
"""
Counts the number of newlines at the end of a string. This is used during
the jinja2 templating to ensure the count matches the input, since some newlines
may be thrown away during the templating.
"""
i = len(in_str)
j = i - 1
try:
while in_str[j] == '\n':
j -= 1
except IndexError:
# Uncommon cases: zero length string and string containing only newlines
return i
return i - 1 - j
@property
def available_variables(self) -> dict[str, t.Any] | ChainMap[str, t.Any]:
"""Available variables this instance will use when templating."""
# DTFIX-RELEASE: ensure that we're always accessing this as a shallow container-level snapshot, and eliminate uses of anything
# that directly mutates this value. _new_context may resolve this for us?
if self._variables is None:
self._variables = self._variables_factory() if self._variables_factory else {}
return self._variables
@available_variables.setter
def available_variables(self, variables: dict[str, t.Any]) -> None:
self._variables = variables
def resolve_variable_expression(
self,
expression: str,
*,
local_variables: dict[str, t.Any] | None = None,
) -> t.Any:
"""
Resolve a potentially untrusted string variable expression consisting only of valid identifiers, integers, dots, and indexing containing these.
Optional local variables may be provided, which can only be referenced directly by the given expression.
Valid: x, x.y, x[y].z, x[1], 1, x[y.z]
Error: 'x', x['y'], q('env')
"""
components = re.split(r'[.\[\]]', expression)
try:
for component in components:
if re.fullmatch('[0-9]*', component):
continue # allow empty strings and integers
validate_variable_name(component)
except Exception as ex:
raise AnsibleError(f'Invalid variable expression: {expression}', obj=expression) from ex
return self.evaluate_expression(TrustedAsTemplate().tag(expression), local_variables=local_variables)
@staticmethod
def variable_name_as_template(name: str) -> str:
"""Return a trusted template string that will resolve the provided variable name. Raises an error if `name` is not a valid identifier."""
validate_variable_name(name)
return AnsibleTagHelper.tag('{{' + name + '}}', (AnsibleTagHelper.tags(name) | {TrustedAsTemplate()}))
def transform(self, variable: t.Any) -> t.Any:
"""Recursively apply transformations to the given value and return the result."""
return self.template(variable, mode=TemplateMode.ALWAYS_FINALIZE, lazy_options=LazyOptions.SKIP_TEMPLATES_AND_ACCESS)
def template(
self,
variable: t.Any, # DTFIX-RELEASE: once we settle the new/old API boundaries, rename this (here and in other methods)
*,
options: TemplateOptions = TemplateOptions.DEFAULT,
mode: TemplateMode = TemplateMode.DEFAULT,
lazy_options: LazyOptions = LazyOptions.DEFAULT,
) -> t.Any:
"""Templates (possibly recursively) any given data as input."""
original_variable = variable
for _attempt in range(TRANSFORM_CHAIN_LIMIT):
if variable is None or (value_type := type(variable)) in IGNORE_SCALAR_VAR_TYPES:
return variable # quickly ignore supported scalar types which are not be templated
value_is_str = isinstance(variable, str)
if template_ctx := TemplateContext.current(optional=True):
stop_on_template = template_ctx.stop_on_template
else:
stop_on_template = False
if mode is TemplateMode.STOP_ON_TEMPLATE:
stop_on_template = True
with (
TemplateContext(template_value=variable, templar=self, options=options, stop_on_template=stop_on_template) as ctx,
DeprecatedAccessAuditContext.when(ctx.is_top_level),
):
try:
if not value_is_str:
# transforms are currently limited to non-str types as an optimization
if (transform := _type_transform_mapping.get(value_type)) and value_type.__name__ not in lazy_options.unmask_type_names:
variable = transform(variable)
continue
template_result = _AnsibleLazyTemplateMixin._try_create(variable, lazy_options)
elif not lazy_options.template:
template_result = variable
elif not is_possibly_template(variable, options.overrides):
template_result = variable
elif not self._trust_check(variable, skip_handler=stop_on_template):
template_result = variable
elif stop_on_template:
raise TemplateEncountered()
else:
compiled_template = self._compile_template(variable, options)
template_result = compiled_template(self.available_variables)
template_result = self._post_render_mutation(variable, template_result, options)
except TemplateEncountered:
raise
except Exception as ex:
template_result = defer_template_error(ex, variable, is_expression=False)
if ctx.is_top_level or mode is TemplateMode.ALWAYS_FINALIZE:
template_result = self._finalize_top_level_template_result(
variable, options, template_result, stop_on_container=mode is TemplateMode.STOP_ON_CONTAINER
)
return template_result
raise AnsibleTemplateTransformLimitError(obj=original_variable)
@staticmethod
def _finalize_top_level_template_result(
variable: t.Any,
options: TemplateOptions,
template_result: t.Any,
is_expression: bool = False,
stop_on_container: bool = False,
) -> t.Any:
"""
This method must be called for expressions and top-level templates to recursively finalize the result.
This renders any embedded templates and triggers `Marker` and omit behaviors.
"""
try:
if template_result is Omit:
# When the template result is Omit, raise an AnsibleValueOmittedError if value_for_omit is Omit, otherwise return value_for_omit.
# Other occurrences of Omit will simply drop out of containers during _finalize_template_result.
if options.value_for_omit is Omit:
raise AnsibleValueOmittedError()
return options.value_for_omit # trust that value_for_omit is an allowed type
if stop_on_container and type(template_result) in AnsibleTaggedObject._collection_types:
# Use of stop_on_container implies the caller will perform necessary checks on values,
# most likely by passing them back into the templating system.
try:
return template_result._non_lazy_copy()
except AttributeError:
return template_result # non-lazy containers are returned as-is
return _finalize_template_result(template_result, FinalizeMode.TOP_LEVEL)
except TemplateEncountered:
raise
except Exception as ex:
raise_from: BaseException
if isinstance(ex, MarkerError):
exception_to_raise = ex.source._as_exception()
# MarkerError is never suitable for use as the cause of another exception, it is merely a raiseable container for the source marker
# used for flow control (so its stack trace is rarely useful). However, if the source derives from a ExceptionMarker, its contained
# exception (previously raised) should be used as the cause. Other sources do not contain exceptions, so cannot provide a cause.
raise_from = exception_to_raise if isinstance(ex.source, ExceptionMarker) else None
else:
exception_to_raise = ex
raise_from = ex
exception_to_raise = create_template_error(exception_to_raise, variable, is_expression)
if exception_to_raise is ex:
raise # when the exception to raise is the active exception, just re-raise it
if exception_to_raise is raise_from:
raise_from = exception_to_raise.__cause__ # preserve the exception's cause, if any, otherwise no cause will be used
raise exception_to_raise from raise_from # always raise from something to avoid the currently active exception becoming __context__
def _compile_template(self, template: str, options: TemplateOptions) -> t.Callable[[c.Mapping[str, t.Any]], t.Any]:
# NOTE: Creating an overlay that lives only inside _compile_template means that overrides are not applied
# when templating nested variables, where Templar.environment is used, not the overlay. They are, however,
# applied to includes and imports.
try:
stripped_template, env = self._create_overlay(template, options.overrides)
with _TemplateCompileContext(escape_backslashes=options.escape_backslashes):
return t.cast(AnsibleTemplate, env.from_string(stripped_template))
except Exception as ex:
return self._defer_jinja_compile_error(ex, template, False)
def _compile_expression(self, expression: str, options: TemplateOptions) -> t.Callable[[c.Mapping[str, t.Any]], t.Any]:
"""
Compile a Jinja expression, applying optional compile-time behavior via an environment overlay (if needed). The overlay is
necessary to avoid mutating settings on the Templar's shared environment, which could be visible to other code running concurrently.
In the specific case of escape_backslashes, the setting only applies to a top-level template at compile-time, not runtime, to
ensure that any nested template calls (e.g., include and import) do not inherit the (lack of) escaping behavior.
"""
try:
with _TemplateCompileContext(escape_backslashes=options.escape_backslashes):
return AnsibleTemplateExpression(self.environment.compile_expression(expression, False))
except Exception as ex:
return self._defer_jinja_compile_error(ex, expression, True)
def _defer_jinja_compile_error(self, ex: Exception, variable: str, is_expression: bool) -> t.Callable[[c.Mapping[str, t.Any]], t.Any]:
deferred_error = defer_template_error(ex, variable, is_expression=is_expression)
def deferred_exception(_jinja_vars: c.Mapping[str, t.Any]) -> t.Any:
# a template/expression compile error always results in a single node representing the compile error
return self.marker_behavior.handle_marker(deferred_error)
return deferred_exception
def _post_render_mutation(self, template: str, result: t.Any, options: TemplateOptions) -> t.Any:
if options.preserve_trailing_newlines and isinstance(result, str):
# The low level calls above do not preserve the newline
# characters at the end of the input data, so we
# calculate the difference in newlines and append them
# to the resulting output for parity
#
# Using AnsibleEnvironment's keep_trailing_newline instead would
# result in change in behavior when trailing newlines
# would be kept also for included templates, for example:
# "Hello {% include 'world.txt' %}!" would render as
# "Hello world\n!\n" instead of "Hello world!\n".
data_newlines = self._count_newlines_from_end(template)
res_newlines = self._count_newlines_from_end(result)
if data_newlines > res_newlines:
newlines = options.overrides.newline_sequence * (data_newlines - res_newlines)
result = AnsibleTagHelper.tag_copy(result, result + newlines)
# If the input string template was source-tagged and the result is not, propagate the source tag to the new value.
# This provides further contextual information when a template-derived value/var causes an error.
if not Origin.is_tagged_on(result) and (origin := Origin.get_tag(template)):
try:
result = origin.tag(result)
except NotTaggableError:
pass # best effort- if we can't, oh well
return result
def is_template(self, data: t.Any, overrides: TemplateOverrides = TemplateOverrides.DEFAULT) -> bool:
"""
Evaluate the input data to determine if it contains a template, even if that template is invalid. Containers will be recursively searched.
Objects subject to template-time transforms that do not yield a template are not considered templates by this method.
Gating a conditional call to `template` with this method is redundant and inefficient -- request templating unconditionally instead.
"""
options = TemplateOptions(overrides=overrides) if overrides is not TemplateOverrides.DEFAULT else TemplateOptions.DEFAULT
try:
self.template(data, options=options, mode=TemplateMode.STOP_ON_TEMPLATE)
except TemplateEncountered:
return True
else:
return False
def resolve_to_container(self, variable: t.Any, options: TemplateOptions = TemplateOptions.DEFAULT) -> t.Any:
"""
Recursively resolve scalar string template input, stopping at the first container encountered (if any).
Used for e.g., partial templating of task arguments, where the plugin needs to handle final resolution of some args internally.
"""
return self.template(variable, options=options, mode=TemplateMode.STOP_ON_CONTAINER)
def evaluate_expression(
self,
expression: str,
*,
local_variables: dict[str, t.Any] | None = None,
escape_backslashes: bool = True,
_render_jinja_const_template: bool = False,
) -> t.Any:
"""
Evaluate a trusted string expression and return its result.
Optional local variables may be provided, which can only be referenced directly by the given expression.
"""
if not isinstance(expression, str):
raise TypeError(f"Expressions must be {str!r}, got {type(expression)!r}.")
options = TemplateOptions(escape_backslashes=escape_backslashes, preserve_trailing_newlines=False)
with (
TemplateContext(template_value=expression, templar=self, options=options, _render_jinja_const_template=_render_jinja_const_template) as ctx,
DeprecatedAccessAuditContext.when(ctx.is_top_level),
):
try:
if not TrustedAsTemplate.is_tagged_on(expression):
raise TemplateTrustCheckFailedError(obj=expression)
template_variables = ChainMap(local_variables, self.available_variables) if local_variables else self.available_variables
compiled_template = self._compile_expression(expression, options)
template_result = compiled_template(template_variables)
template_result = self._post_render_mutation(expression, template_result, options)
except Exception as ex:
template_result = defer_template_error(ex, expression, is_expression=True)
return self._finalize_top_level_template_result(expression, options, template_result, is_expression=True)
_BROKEN_CONDITIONAL_ALLOWED_FRAGMENT = 'Broken conditionals are currently allowed because the `ALLOW_BROKEN_CONDITIONALS` configuration option is enabled.'
_CONDITIONAL_AS_TEMPLATE_MSG = 'Conditionals should not be surrounded by templating delimiters such as {{ }} or {% %}.'
def _strip_conditional_handle_empty(self, conditional) -> t.Any:
"""
Strips leading/trailing whitespace from the input expression.
If `ALLOW_BROKEN_CONDITIONALS` is enabled, None/empty is coerced to True (legacy behavior, deprecated).
Otherwise, None/empty results in a broken conditional error being raised.
"""
if isinstance(conditional, str):
# Leading/trailing whitespace on conditional expressions is not a problem, except we can't tell if the expression is empty (which *is* a problem).
# Always strip conditional input strings. Neither conditional expressions nor all-template conditionals have legit reasons to preserve
# surrounding whitespace, and they complicate detection and processing of all-template fallback cases.
conditional = AnsibleTagHelper.tag_copy(conditional, conditional.strip())
if conditional in (None, ''):
# deprecated backward-compatible behavior; None/empty input conditionals are always True
if _TemplateConfig.allow_broken_conditionals:
_display.deprecated(
msg='Empty conditional expression was evaluated as True.',
help_text=self._BROKEN_CONDITIONAL_ALLOWED_FRAGMENT,
obj=conditional,
version='2.23',
)
return True
raise AnsibleBrokenConditionalError("Empty conditional expressions are not allowed.", obj=conditional)
return conditional
def _normalize_and_evaluate_conditional(self, conditional: str | bool) -> t.Any:
"""Validate and normalize a conditional input value, resolving allowed embedded template cases and evaluating the resulting expression."""
conditional = self._strip_conditional_handle_empty(conditional)
# this must follow `_strip_conditional_handle_empty`, since None/empty are coerced to bool (deprecated)
if type(conditional) is bool: # pylint: disable=unidiomatic-typecheck
return conditional
try:
if not isinstance(conditional, str):
if _TemplateConfig.allow_broken_conditionals:
# because the input isn't a string, the result will never be a bool; the broken conditional warning in the caller will apply on the result
return self.template(conditional, mode=TemplateMode.ALWAYS_FINALIZE)
raise AnsibleBrokenConditionalError(message="Conditional expressions must be strings.", obj=conditional)
if is_possibly_all_template(conditional):
# Indirection of trusted expressions is always allowed. If the expression appears to be entirely wrapped in template delimiters,
# we must resolve it. e.g. `when: "{{ some_var_resolving_to_a_trusted_expression_string }}"`.
# Some invalid meta-templating corner cases may sneak through here (e.g., `when: '{{ "foo" }} == {{ "bar" }}'`); these will
# result in an untrusted expression error.
result = self.template(conditional, mode=TemplateMode.ALWAYS_FINALIZE)
result = self._strip_conditional_handle_empty(result)
if not isinstance(result, str):
_display.deprecated(msg=self._CONDITIONAL_AS_TEMPLATE_MSG, obj=conditional, version='2.23')
return result # not an expression
# The only allowed use of templates for conditionals is for indirect usage of an expression.
# Any other usage should simply be an expression, not an attempt at meta templating.
expression = result
else:
expression = conditional
# Disable escape_backslashes when processing conditionals, to maintain backwards compatibility.
# This is necessary because conditionals were previously evaluated using {% %}, which was *NOT* affected by escape_backslashes.
# Now that conditionals use expressions, they would be affected by escape_backslashes if it was not disabled.
return self.evaluate_expression(expression, escape_backslashes=False, _render_jinja_const_template=True)
except AnsibleUndefinedVariable as ex:
# DTFIX-FUTURE: we're only augmenting the message for context here; once we have proper contextual tracking, we can dump the re-raise
raise AnsibleUndefinedVariable("Error while evaluating conditional.", obj=conditional) from ex
def evaluate_conditional(self, conditional: str | bool) -> bool:
"""
Evaluate a trusted string expression or boolean and return its boolean result. A non-boolean result will raise `AnsibleBrokenConditionalError`.
The ALLOW_BROKEN_CONDITIONALS configuration option can temporarily relax this requirement, allowing truthy conditionals to succeed.
"""
result = self._normalize_and_evaluate_conditional(conditional)
if isinstance(result, bool):
return result
bool_result = bool(result)
msg = (
f'Conditional result was {textwrap.shorten(str(result), width=40)!r} of type {native_type_name(result)!r}, '
f'which evaluates to {bool_result}. Conditionals must have a boolean result.'
)
if _TemplateConfig.allow_broken_conditionals:
_display.deprecated(
msg=msg,
obj=conditional,
help_text=self._BROKEN_CONDITIONAL_ALLOWED_FRAGMENT,
version='2.23',
)
return bool_result
raise AnsibleBrokenConditionalError(msg, obj=conditional)
@staticmethod
def _trust_check(value: str, skip_handler: bool = False) -> bool:
"""
Return True if the given value is trusted for templating, otherwise return False.
When the value is not trusted, a warning or error may be generated, depending on configuration.
"""
if TrustedAsTemplate.is_tagged_on(value):
return True
if not skip_handler:
with Skippable, _TemplateConfig.untrusted_template_handler.handle(TemplateTrustCheckFailedError, skip_on_ignore=True):
raise TemplateTrustCheckFailedError(obj=value)
return False
ansible_core-2.19.0b4/lib/ansible/_internal/_templating/_errors.py 0000644 0000000 0000000 00000002426 15010426755 023713 0 ustar 00root root from __future__ import annotations
from ansible.errors import AnsibleTemplatePluginError
class AnsibleTemplatePluginRuntimeError(AnsibleTemplatePluginError):
"""The specified template plugin (lookup/filter/test) raised an exception during execution."""
def __init__(self, plugin_type: str, plugin_name: str) -> None:
super().__init__(f'The {plugin_type} plugin {plugin_name!r} failed.')
class AnsibleTemplatePluginLoadError(AnsibleTemplatePluginError):
"""The specified template plugin (lookup/filter/test) failed to load."""
def __init__(self, plugin_type: str, plugin_name: str) -> None:
super().__init__(f'The {plugin_type} plugin {plugin_name!r} failed to load.')
class AnsibleTemplatePluginNotFoundError(AnsibleTemplatePluginError, KeyError):
"""
The specified template plugin (lookup/filter/test) was not found.
This exception extends KeyError since Jinja filter/test resolution requires a KeyError to detect missing plugins.
Jinja compilation fails if a non-KeyError is raised for a missing filter/test, even if the plugin will not be invoked (inconsistent with stock Jinja).
"""
def __init__(self, plugin_type: str, plugin_name: str) -> None:
super().__init__(f'The {plugin_type} plugin {plugin_name!r} was not found.')
ansible_core-2.19.0b4/lib/ansible/_internal/_templating/_jinja_bits.py 0000644 0000000 0000000 00000134115 15010426755 024514 0 ustar 00root root from __future__ import annotations
import ast
import collections.abc as c
import dataclasses
import enum
import pathlib
import tempfile
import types
import typing as t
from collections import ChainMap
import jinja2.nodes
from jinja2 import pass_context, defaults, TemplateSyntaxError, FileSystemLoader
from jinja2.environment import Environment, Template, TemplateModule, TemplateExpression
from jinja2.compiler import Frame
from jinja2.lexer import TOKEN_VARIABLE_BEGIN, TOKEN_VARIABLE_END, TOKEN_STRING, Lexer
from jinja2.nativetypes import NativeCodeGenerator
from jinja2.nodes import Const, EvalContext
from jinja2.runtime import Context
from jinja2.sandbox import ImmutableSandboxedEnvironment
from jinja2.utils import missing, LRUCache
from ansible.utils.display import Display
from ansible.errors import AnsibleVariableTypeError, AnsibleTemplateSyntaxError, AnsibleTemplateError
from ansible.module_utils.common.text.converters import to_text
from ansible.module_utils._internal._datatag import (
_AnsibleTaggedDict,
_AnsibleTaggedList,
_AnsibleTaggedTuple,
_AnsibleTaggedStr,
AnsibleTagHelper,
)
from ansible._internal._errors._handler import ErrorAction
from ansible._internal._datatag._tags import Origin, TrustedAsTemplate
from ._access import AnsibleAccessContext
from ._datatag import _JinjaConstTemplate
from ._utils import LazyOptions
from ._jinja_common import (
MarkerError,
Marker,
CapturedExceptionMarker,
UndefinedMarker,
_TemplateConfig,
TruncationMarker,
validate_arg_type,
JinjaCallContext,
)
from ._jinja_plugins import JinjaPluginIntercept, _query, _lookup, _now, _wrap_plugin_output, get_first_marker_arg, _DirectCall, _jinja_const_template_warning
from ._lazy_containers import (
_AnsibleLazyTemplateMixin,
_AnsibleLazyTemplateDict,
_AnsibleLazyTemplateList,
_AnsibleLazyAccessTuple,
lazify_container_args,
lazify_container_kwargs,
lazify_container,
register_known_types,
)
from ._utils import Omit, TemplateContext, PASS_THROUGH_SCALAR_VAR_TYPES
from ansible.module_utils._internal._json._profiles import _json_subclassable_scalar_types
from ansible.module_utils import _internal
from ansible.module_utils._internal import _ambient_context, _dataclass_validation
from ansible.plugins.loader import filter_loader, test_loader
from ansible.vars.hostvars import HostVars, HostVarsVars
from ...module_utils.datatag import native_type_name
JINJA2_OVERRIDE = '#jinja2:'
display = Display()
@dataclasses.dataclass(kw_only=True, slots=True, frozen=True)
class TemplateOverrides:
DEFAULT: t.ClassVar[t.Self]
block_start_string: str = defaults.BLOCK_START_STRING
block_end_string: str = defaults.BLOCK_END_STRING
variable_start_string: str = defaults.VARIABLE_START_STRING
variable_end_string: str = defaults.VARIABLE_END_STRING
comment_start_string: str = defaults.COMMENT_START_STRING
comment_end_string: str = defaults.COMMENT_END_STRING
line_statement_prefix: str | None = defaults.LINE_STATEMENT_PREFIX
line_comment_prefix: str | None = defaults.LINE_COMMENT_PREFIX
trim_blocks: bool = True # AnsibleEnvironment overrides this default, so don't use the Jinja default here
lstrip_blocks: bool = defaults.LSTRIP_BLOCKS
newline_sequence: t.Literal['\n', '\r\n', '\r'] = defaults.NEWLINE_SEQUENCE
keep_trailing_newline: bool = defaults.KEEP_TRAILING_NEWLINE
def __post_init__(self) -> None:
pass # overridden by _dataclass_validation._inject_post_init_validation
def _post_validate(self) -> None:
if not (self.block_start_string != self.variable_start_string != self.comment_start_string != self.block_start_string):
raise ValueError('Block, variable and comment start strings must be different.')
def overlay_kwargs(self) -> dict[str, t.Any]:
"""
Return a dictionary of arguments for passing to Environment.overlay.
The dictionary will be empty if all fields have their default value.
"""
# DTFIX-FUTURE: calculate default/non-default during __post_init__
fields = [(field, getattr(self, field.name)) for field in dataclasses.fields(self)]
kwargs = {field.name: value for field, value in fields if value != field.default}
return kwargs
def _contains_start_string(self, value: str) -> bool:
"""Returns True if the given value contains a variable, block or comment start string."""
# DTFIX-FUTURE: this is inefficient, use a compiled regex instead
for marker in (self.block_start_string, self.variable_start_string, self.comment_start_string):
if marker in value:
return True
return False
def _starts_and_ends_with_jinja_delimiters(self, value: str) -> bool:
"""Returns True if the given value starts and ends with Jinja variable, block or comment delimiters."""
# DTFIX-FUTURE: this is inefficient, use a compiled regex instead
for marker in (self.block_start_string, self.variable_start_string, self.comment_start_string):
if value.startswith(marker):
break
else:
return False
for marker in (self.block_end_string, self.variable_end_string, self.comment_end_string):
if value.endswith(marker):
return True
return False
def _extract_template_overrides(self, template: str) -> tuple[str, TemplateOverrides]:
if template.startswith(JINJA2_OVERRIDE):
eol = template.find('\n')
if eol == -1:
raise ValueError(f"Missing newline after {JINJA2_OVERRIDE!r} override.")
line = template[len(JINJA2_OVERRIDE) : eol]
template = template[eol + 1 :]
override_kwargs = {}
for pair in line.split(','):
if not pair.strip():
raise ValueError(f"Empty {JINJA2_OVERRIDE!r} override pair not allowed.")
if ':' not in pair:
raise ValueError(f"Missing key-value separator `:` in {JINJA2_OVERRIDE!r} override pair {pair!r}.")
key, val = pair.split(':', 1)
key = key.strip()
if key not in _TEMPLATE_OVERRIDE_FIELD_NAMES:
raise ValueError(f"Invalid {JINJA2_OVERRIDE!r} override key {key!r}.")
override_kwargs[key] = ast.literal_eval(val)
overrides = dataclasses.replace(self, **override_kwargs)
else:
overrides = self
return template, overrides
def merge(self, kwargs: dict[str, t.Any] | None, /) -> TemplateOverrides:
"""Return a new instance based on the current instance with the given kwargs overridden."""
if kwargs:
return self.from_kwargs(dataclasses.asdict(self) | kwargs)
return self
@classmethod
def from_kwargs(cls, kwargs: dict[str, t.Any] | None, /) -> TemplateOverrides:
"""TemplateOverrides instance factory; instances resolving to all default values will instead return the DEFAULT singleton for optimization."""
if kwargs:
value = cls(**kwargs)
if value.overlay_kwargs():
return value
return cls.DEFAULT
_dataclass_validation.inject_post_init_validation(TemplateOverrides, allow_subclasses=True)
TemplateOverrides.DEFAULT = TemplateOverrides()
_TEMPLATE_OVERRIDE_FIELD_NAMES: t.Final[tuple[str, ...]] = tuple(sorted(field.name for field in dataclasses.fields(TemplateOverrides)))
class AnsibleContext(Context):
"""
A custom context which intercepts resolve_or_missing() calls and
runs them through AnsibleAccessContext. This allows usage of variables
to be tracked. If needed, values can also be modified before being returned.
"""
environment: AnsibleEnvironment # narrow the type specified by the base
def __init__(self, *args, **kwargs):
super(AnsibleContext, self).__init__(*args, **kwargs)
__repr__ = object.__repr__ # prevent Jinja from dumping vars in case this gets repr'd
def get_all(self):
"""
Override Jinja's default get_all to return all vars in the context as a ChainMap with a mutable layer at the bottom.
This provides some isolation against accidental changes to inherited variable contexts without requiring copies.
"""
layers = []
if self.vars:
layers.append(self.vars)
if self.parent:
layers.append(self.parent)
# HACK: always include a sacrificial plain-dict on the bottom layer, since Jinja's debug and stacktrace rewrite code invokes
# `__setitem__` outside a call context; this will ensure that it always occurs on a plain dict instead of a lazy one.
return ChainMap({}, *layers)
# noinspection PyShadowingBuiltins
def derived(self, locals: t.Optional[t.Dict[str, t.Any]] = None) -> Context:
# this is a clone of Jinja's impl of derived, but using our lazy-aware _new_context
context = _new_context(
environment=self.environment,
template_name=self.name,
blocks={},
shared=True,
jinja_locals=locals,
jinja_vars=self.get_all(),
)
context.eval_ctx = self.eval_ctx
context.blocks.update((k, list(v)) for k, v in self.blocks.items())
return context
def keys(self, *args, **kwargs):
"""Base Context delegates to `dict.keys` against `get_all`, which would fail since we return a ChainMap. No known usage."""
raise NotImplementedError()
def values(self, *args, **kwargs):
"""Base Context delegates to `dict.values` against `get_all`, which would fail since we return a ChainMap. No known usage."""
raise NotImplementedError()
def items(self, *args, **kwargs):
"""Base Context delegates to built-in `dict.items` against `get_all`, which would fail since we return a ChainMap. No known usage."""
raise NotImplementedError()
@dataclasses.dataclass(frozen=True, kw_only=True, slots=True)
class ArgSmuggler:
"""
Utility wrapper to wrap/unwrap args passed to Jinja `Template.render` and `TemplateExpression.__call__`.
e.g., see https://github.com/pallets/jinja/blob/3.1.3/src/jinja2/environment.py#L1296 and
https://github.com/pallets/jinja/blob/3.1.3/src/jinja2/environment.py#L1566.
"""
jinja_vars: c.Mapping[str, t.Any] | None
@classmethod
def package_jinja_vars(cls, jinja_vars: c.Mapping[str, t.Any]) -> dict[str, ArgSmuggler]:
"""Wrap the supplied vars dict in an ArgSmuggler to prevent premature templating from Jinja's internal dict copy."""
return dict(_smuggled_vars=ArgSmuggler(jinja_vars=jinja_vars))
@classmethod
def extract_jinja_vars(cls, maybe_smuggled_vars: c.Mapping[str, t.Any] | None) -> c.Mapping[str, t.Any]:
"""
If the supplied vars dict contains an ArgSmuggler instance with the expected key, unwrap it and return the smuggled value.
Otherwise, return the supplied dict as-is.
"""
if maybe_smuggled_vars and ((smuggler := maybe_smuggled_vars.get('_smuggled_vars')) and isinstance(smuggler, ArgSmuggler)):
return smuggler.jinja_vars
return maybe_smuggled_vars
class AnsibleTemplateExpression:
"""
Wrapper around Jinja's TemplateExpression for converting MarkerError back into Marker.
This is needed to make expression error handling consistent with templates, since Jinja does not support a custom type for Environment.compile_expression.
"""
def __init__(self, template_expression: TemplateExpression) -> None:
self._template_expression = template_expression
def __call__(self, jinja_vars: c.Mapping[str, t.Any]) -> t.Any:
try:
return self._template_expression(ArgSmuggler.package_jinja_vars(jinja_vars))
except MarkerError as ex:
return ex.source
class AnsibleTemplate(Template):
"""
A helper class, which prevents Jinja2 from running lazy containers through dict().
"""
_python_source_temp_path: pathlib.Path | None = None
def __del__(self):
# DTFIX-RELEASE: this still isn't working reliably; something else must be keeping the template object alive
if self._python_source_temp_path:
self._python_source_temp_path.unlink(missing_ok=True)
def __call__(self, jinja_vars: c.Mapping[str, t.Any]) -> t.Any:
return self.render(ArgSmuggler.package_jinja_vars(jinja_vars))
# noinspection PyShadowingBuiltins
def new_context(
self,
vars: c.Mapping[str, t.Any] | None = None,
shared: bool = False,
locals: c.Mapping[str, t.Any] | None = None,
) -> Context:
return _new_context(
environment=self.environment,
template_name=self.name,
blocks=self.blocks,
shared=shared,
jinja_locals=locals,
jinja_vars=ArgSmuggler.extract_jinja_vars(vars),
jinja_globals=self.globals,
)
class AnsibleCodeGenerator(NativeCodeGenerator):
"""
Custom code generation behavior to support deprecated Ansible features and fill in gaps in Jinja native.
This can be removed once the deprecated Ansible features are removed and the native fixes are upstreamed in Jinja.
"""
def _output_const_repr(self, group: t.Iterable[t.Any]) -> str:
"""
Prevent Jinja's code generation from stringifying single nodes before generating its repr.
This complements the behavioral change in AnsibleEnvironment.concat which returns single nodes without stringifying them.
"""
# DTFIX-FUTURE: contribute this upstream as a fix to Jinja's native support
group_list = list(group)
if len(group_list) == 1:
return repr(group_list[0])
# NB: This is slightly more efficient than Jinja's _output_const_repr, which generates a throw-away list instance to pass to join.
# Before removing this, ensure that upstream Jinja has this change.
return repr("".join(map(str, group_list)))
def visit_Const(self, node: Const, frame: Frame) -> None:
"""
Override Jinja's visit_Const to inject a runtime call to AnsibleEnvironment._access_const for constant strings that are possibly templates, which
may require special handling at runtime. See that method for details. An example that hits this path:
{{ lookup("file", "{{ output_dir }}/bla") }}
"""
value = node.as_const(frame.eval_ctx)
if _TemplateConfig.allow_embedded_templates and type(value) is str and is_possibly_template(value): # pylint: disable=unidiomatic-typecheck
# deprecated: description='embedded Jinja constant string template support' core_version='2.23'
self.write(f'environment._access_const({value!r})')
else:
# NB: This is actually more efficient than Jinja's visit_Const, which contains obsolete (as of Py2.7/3.1) float conversion instance checks. Before
# removing this override entirely, ensure that upstream Jinja has removed the obsolete code.
# See https://docs.python.org/release/2.7/whatsnew/2.7.html#python-3-1-features for more details.
self.write(repr(value))
@pass_context
def _ansible_finalize(_ctx: AnsibleContext, value: t.Any) -> t.Any:
"""
This function is called by Jinja with the result of each variable template block (e.g., {{ }}) encountered in a template.
The pass_context decorator prevents finalize from being called on constants at template compile time.
The passed in AnsibleContext is unused -- it is the result of using the pass_context decorator.
The important part for us is that this blocks constant folding, which ensures our custom visit_Const is used.
It also ensures that template results are wrapped in lazy containers.
"""
return lazify_container(value)
@dataclasses.dataclass(kw_only=True, slots=True)
class _TemplateCompileContext(_ambient_context.AmbientContextBase):
"""
This context is active during Ansible's explicit compilation of templates/expressions, but not during Jinja's runtime compilation.
Historically, Ansible-specific pre-processing like `escape_backslashes` was not applied to imported/included templates.
"""
escape_backslashes: bool
class _CompileStateSmugglingCtx(_ambient_context.AmbientContextBase):
template_source: str | None = None
python_source: str | None = None
python_source_temp_path: pathlib.Path | None = None
class AnsibleLexer(Lexer):
"""
Lexer override to escape backslashes in string constants within Jinja expressions; prevents Jinja from double-escaping them.
NOTE: This behavior is only applied to string constants within Jinja expressions (eg {{ "c:\newfile" }}), *not* statements ("{% set foo="c:\\newfile" %}").
This is useful when templates are sourced from YAML double-quoted strings, as it avoids having backslashes processed twice: first by the
YAML parser, and then again by the Jinja parser. Instead, backslashes are only processed by YAML.
Example YAML:
- debug:
msg: "Test Case 1\\3; {{ test1_name | regex_replace('^(.*)_name$', '\\1')}}"
Since the outermost YAML string is double-quoted, the YAML parser converts the double backslashes to single backslashes. Without escaping, Jinja
would see only a single backslash ('\1') while processing the embedded template expression, interpret it as an escape sequence, and convert it
to '\x01' (ASCII "SOH"). This is clearly not the intended `\1` backreference argument to the `regex_replace` filter (which would require the
double-escaped string '\\\\1' to yield the intended result).
Since the "\\3" in the input YAML was not part of a template expression, the YAML-parsed "\3" remains after Jinja rendering. This would be
confusing for playbook authors, as different escaping rules would be needed inside and outside the template expression.
When templates are not sourced from YAML, escaping backslashes will prevent use of backslash escape sequences such as "\n" and "\t".
See relevant Jinja lexer impl at e.g.: https://github.com/pallets/jinja/blob/3.1.2/src/jinja2/lexer.py#L646-L653.
"""
def tokeniter(self, *args, **kwargs) -> t.Iterator[t.Tuple[int, str, str]]:
"""Pre-escape backslashes in expression ({{ }}) raw string constants before Jinja's Lexer.wrap() can interpret them as ASCII escape sequences."""
token_stream = super().tokeniter(*args, **kwargs)
# if we have no context, Jinja's doing a nested compile at runtime (eg, import/include); historically, no backslash escaping is performed
if not (tcc := _TemplateCompileContext.current(optional=True)) or not tcc.escape_backslashes:
yield from token_stream
return
in_variable = False
for token in token_stream:
token_type = token[1]
if token_type == TOKEN_VARIABLE_BEGIN:
in_variable = True
elif token_type == TOKEN_VARIABLE_END:
in_variable = False
elif in_variable and token_type == TOKEN_STRING:
token = token[0], token_type, token[2].replace('\\', '\\\\')
yield token
def defer_template_error(ex: Exception, variable: t.Any, *, is_expression: bool) -> Marker:
if not ex.__traceback__:
raise AssertionError('ex must be a previously raised exception')
if isinstance(ex, MarkerError):
return ex.source
exception_to_raise = create_template_error(ex, variable, is_expression)
if exception_to_raise is ex:
return CapturedExceptionMarker(ex) # capture the previously raised exception
try:
raise exception_to_raise from ex # raise the newly synthesized exception before capturing it
except Exception as captured_ex:
return CapturedExceptionMarker(captured_ex)
def create_template_error(ex: Exception, variable: t.Any, is_expression: bool) -> AnsibleTemplateError:
if isinstance(ex, AnsibleTemplateError):
exception_to_raise = ex
else:
kind = "expression" if is_expression else "template"
ex_type = AnsibleTemplateError # always raise an AnsibleTemplateError/subclass
if isinstance(ex, RecursionError):
msg = f"Recursive loop detected in {kind}."
elif isinstance(ex, TemplateSyntaxError):
msg = f"Syntax error in {kind}."
if is_expression and is_possibly_template(variable):
msg += " Template delimiters are not supported in expressions."
ex_type = AnsibleTemplateSyntaxError
else:
msg = f"Error rendering {kind}."
exception_to_raise = ex_type(msg, obj=variable)
if exception_to_raise.obj is None:
exception_to_raise.obj = TemplateContext.current().template_value
# DTFIX-FUTURE: Look through the TemplateContext hierarchy to find the most recent non-template
# caller and use that for origin when no origin is available on obj. This could be useful for situations where the template
# was embedded in a plugin, or a plugin is otherwise responsible for losing the origin and/or trust. We can't just use the first
# non-template caller as that will lead to false positives for re-entrant calls (e.g. template plugins that call into templar).
return exception_to_raise
# DTFIX-RELEASE: implement CapturedExceptionMarker deferral support on call (and lookup), filter/test plugins, etc.
# also update the protomatter integration test once this is done (the test was written differently since this wasn't done yet)
_BUILTIN_FILTER_ALIASES: dict[str, str] = {}
_BUILTIN_TEST_ALIASES: dict[str, str] = {
'!=': 'ne',
'<': 'lt',
'<=': 'le',
'==': 'eq',
'>': 'gt',
'>=': 'ge',
}
_BUILTIN_FILTERS = filter_loader._wrap_funcs(defaults.DEFAULT_FILTERS, _BUILTIN_FILTER_ALIASES)
_BUILTIN_TESTS = test_loader._wrap_funcs(t.cast(dict[str, t.Callable], defaults.DEFAULT_TESTS), _BUILTIN_TEST_ALIASES)
class AnsibleEnvironment(ImmutableSandboxedEnvironment):
"""
Our custom environment, which simply allows us to override the class-level
values for the Template and Context classes used by jinja2 internally.
"""
context_class = AnsibleContext
template_class = AnsibleTemplate
code_generator_class = AnsibleCodeGenerator
intercepted_binops = frozenset(('eq',))
_lexer_cache = LRUCache(50)
# DTFIX-FUTURE: bikeshed a name/mechanism to control template debugging
_debuggable_template_source = False
_debuggable_template_source_path: pathlib.Path = pathlib.Path(__file__).parent.parent.parent.parent / '.template_debug_source'
def __init__(self, *args, ansible_basedir: str | None = None, **kwargs) -> None:
if ansible_basedir:
kwargs.update(loader=FileSystemLoader(ansible_basedir))
super().__init__(*args, extensions=_TemplateConfig.jinja_extensions, **kwargs)
self.filters = JinjaPluginIntercept(_BUILTIN_FILTERS, filter_loader) # type: ignore[assignment]
self.tests = JinjaPluginIntercept(_BUILTIN_TESTS, test_loader) # type: ignore[assignment,arg-type]
# future Jinja releases may default-enable autoescape; force-disable to prevent the problems it could cause
# see https://github.com/pallets/jinja/blob/3.1.2/docs/api.rst?plain=1#L69
self.autoescape = False
self.trim_blocks = True
self.undefined = UndefinedMarker
self.finalize = _ansible_finalize
self.globals.update(
range=range, # the sandboxed environment limits range in ways that may cause us problems; use the real Python one
now=_now,
undef=_undef,
omit=Omit,
lookup=_lookup,
query=_query,
q=_query,
)
# Disabling the optimizer prevents compile-time constant expression folding, which prevents our
# visit_Const recursive inline template expansion tricks from working in many cases where Jinja's
# ignorance of our embedded templates are optimized away as fully-constant expressions,
# eg {{ "{{'hi'}}" == "hi" }}. As of Jinja ~3.1, this specifically avoids cases where the @optimizeconst
# visitor decorator performs constant folding, which bypasses our visit_Const impl and causes embedded
# templates to be lost.
# See also optimizeconst impl: https://github.com/pallets/jinja/blob/3.1.0/src/jinja2/compiler.py#L48-L49
self.optimized = False
def get_template(
self,
name: str | Template,
parent: str | None = None,
globals: c.MutableMapping[str, t.Any] | None = None,
) -> Template:
"""Ensures that templates built via `get_template` are also source debuggable."""
with _CompileStateSmugglingCtx.when(self._debuggable_template_source) as ctx:
template_obj = t.cast(AnsibleTemplate, super().get_template(name, parent, globals))
if isinstance(ctx, _CompileStateSmugglingCtx): # only present if debugging is enabled
template_obj._python_source_temp_path = ctx.python_source_temp_path # facilitate deletion of the temp file when template_obj is deleted
return template_obj
@property
def lexer(self) -> AnsibleLexer:
"""Return/cache an AnsibleLexer with settings from the current AnsibleEnvironment"""
# DTFIX-RELEASE: optimization - we should pre-generate the default cached lexer before forking, not leave it to chance (e.g. simple playbooks)
key = tuple(getattr(self, name) for name in _TEMPLATE_OVERRIDE_FIELD_NAMES)
lex = self._lexer_cache.get(key)
if lex is None:
self._lexer_cache[key] = lex = AnsibleLexer(self)
return lex
def call_filter(
self,
name: str,
value: t.Any,
args: c.Sequence[t.Any] | None = None,
kwargs: c.Mapping[str, t.Any] | None = None,
context: Context | None = None,
eval_ctx: EvalContext | None = None,
) -> t.Any:
"""
Ensure that filters directly invoked by plugins will see non-templating lazy containers.
Without this, `_wrap_filter` will wrap `args` and `kwargs` in templating lazy containers.
This provides consistency with plugin output handling by preventing auto-templating of trusted templates passed in native containers.
"""
# DTFIX-RELEASE: need better logic to handle non-list/non-dict inputs for args/kwargs
args = _AnsibleLazyTemplateMixin._try_create(list(args or []), LazyOptions.SKIP_TEMPLATES)
kwargs = _AnsibleLazyTemplateMixin._try_create(kwargs, LazyOptions.SKIP_TEMPLATES)
return super().call_filter(name, value, args, kwargs, context, eval_ctx)
def call_test(
self,
name: str,
value: t.Any,
args: c.Sequence[t.Any] | None = None,
kwargs: c.Mapping[str, t.Any] | None = None,
context: Context | None = None,
eval_ctx: EvalContext | None = None,
) -> t.Any:
"""
Ensure that tests directly invoked by plugins will see non-templating lazy containers.
Without this, `_wrap_test` will wrap `args` and `kwargs` in templating lazy containers.
This provides consistency with plugin output handling by preventing auto-templating of trusted templates passed in native containers.
"""
# DTFIX-RELEASE: need better logic to handle non-list/non-dict inputs for args/kwargs
args = _AnsibleLazyTemplateMixin._try_create(list(args or []), LazyOptions.SKIP_TEMPLATES)
kwargs = _AnsibleLazyTemplateMixin._try_create(kwargs, LazyOptions.SKIP_TEMPLATES)
return super().call_test(name, value, args, kwargs, context, eval_ctx)
def compile_expression(self, source: str, *args, **kwargs) -> TemplateExpression:
# compile_expression parses and passes the tree to from_string; for debug support, activate the context here to capture the intermediate results
with _CompileStateSmugglingCtx.when(self._debuggable_template_source) as ctx:
if isinstance(ctx, _CompileStateSmugglingCtx): # only present if debugging is enabled
ctx.template_source = source
return super().compile_expression(source, *args, **kwargs)
def from_string(self, source: str | jinja2.nodes.Template, *args, **kwargs) -> AnsibleTemplate:
# if debugging is enabled, use existing context when present (e.g., from compile_expression)
current_ctx = _CompileStateSmugglingCtx.current(optional=True) if self._debuggable_template_source else None
with _CompileStateSmugglingCtx.when(self._debuggable_template_source and not current_ctx) as new_ctx:
template_obj = t.cast(AnsibleTemplate, super().from_string(source, *args, **kwargs))
if isinstance(ctx := current_ctx or new_ctx, _CompileStateSmugglingCtx): # only present if debugging is enabled
template_obj._python_source_temp_path = ctx.python_source_temp_path # facilitate deletion of the temp file when template_obj is deleted
return template_obj
def _parse(self, source: str, *args, **kwargs) -> jinja2.nodes.Template:
if csc := _CompileStateSmugglingCtx.current(optional=True):
csc.template_source = source
return super()._parse(source, *args, **kwargs)
def _compile(self, source: str, filename: str) -> types.CodeType:
if csc := _CompileStateSmugglingCtx.current(optional=True):
origin = Origin.get_tag(csc.template_source) or Origin.UNKNOWN
source = '\n'.join(
(
"import sys; breakpoint() if type(sys.breakpointhook) is not type(breakpoint) else None",
f"# original template source from {str(origin)!r}: ",
'\n'.join(f'# {line}' for line in (csc.template_source or '').splitlines()),
source,
)
)
source_temp_dir = self._debuggable_template_source_path
source_temp_dir.mkdir(parents=True, exist_ok=True)
with tempfile.NamedTemporaryFile(dir=source_temp_dir, mode='w', suffix='.py', prefix='j2_src_', delete=False) as source_file:
filename = source_file.name
source_file.write(source)
source_file.flush()
csc.python_source = source
csc.python_source_temp_path = pathlib.Path(filename)
res = super()._compile(source, filename)
return res
@staticmethod
def concat(nodes: t.Iterable[t.Any]) -> t.Any: # type: ignore[override]
node_list = list(_flatten_nodes(nodes))
if not node_list:
return None
# this code is complemented by our tweaked CodeGenerator _output_const_repr that ensures that literal constants
# in templates aren't double-repr'd in the generated code
if len(node_list) == 1:
# DTFIX-RELEASE: determine if we should do managed access here (we *should* have hit them all during templating/resolve, but ?)
return node_list[0]
# In order to ensure that all markers are tripped, do a recursive finalize before we repr (otherwise we can end up
# repr'ing a Marker). This requires two passes, but avoids the need for a parallel reimplementation of all repr methods.
try:
node_list = _finalize_template_result(node_list, FinalizeMode.CONCAT)
except MarkerError as ex:
return ex.source # return the first Marker encountered
return ''.join([to_text(v) for v in node_list])
@staticmethod
def _access_const(const_template: t.LiteralString) -> t.Any:
"""
Called during template rendering on template-looking string constants embedded in the template.
It provides the following functionality:
* Propagates origin from the containing template.
* For backward compatibility when embedded templates are enabled:
* Conditionals - Renders embedded template constants and accesses the result. Warns on each constant immediately.
* Non-conditionals - Tags constants for deferred rendering of templates in lookup terms. Warns on each constant during lookup invocation.
"""
ctx = TemplateContext.current()
if (tv := ctx.template_value) and (origin := Origin.get_tag(tv)):
const_template = origin.tag(const_template)
if ctx._render_jinja_const_template:
_jinja_const_template_warning(const_template, is_conditional=True)
result = ctx.templar.template(TrustedAsTemplate().tag(const_template))
AnsibleAccessContext.current().access(result)
else:
# warnings will be issued when lookup terms processing occurs, to avoid false positives
result = _JinjaConstTemplate().tag(const_template)
return result
def getitem(self, obj: t.Any, argument: t.Any) -> t.Any:
value = super().getitem(obj, argument)
AnsibleAccessContext.current().access(value)
return value
def getattr(self, obj: t.Any, attribute: str) -> t.Any:
"""
Get `attribute` from the attributes of `obj`, falling back to items in `obj`.
If no item was found, return a sandbox-specific `UndefinedMarker` if `attribute` is protected by the sandbox,
otherwise return a normal `UndefinedMarker` instance.
This differs from the built-in Jinja behavior which will not fall back to items if `attribute` is protected by the sandbox.
"""
# example template that uses this: "{{ some.thing }}" -- obj is the "some" dict, attribute is "thing"
is_safe = True
try:
value = getattr(obj, attribute)
except AttributeError:
value = _sentinel
else:
if not (is_safe := self.is_safe_attribute(obj, attribute, value)):
value = _sentinel
if value is _sentinel:
try:
value = obj[attribute]
except (TypeError, LookupError):
return self.undefined(obj=obj, name=attribute) if is_safe else self.unsafe_undefined(obj, attribute)
AnsibleAccessContext.current().access(value)
return value
def call(
self,
__context: Context,
__obj: t.Any,
*args: t.Any,
**kwargs: t.Any,
) -> t.Any:
if _DirectCall.is_marked(__obj):
# Both `_lookup` and `_query` handle arg proxying and `Marker` args internally.
# Performing either before calling them will interfere with that processing.
return super().call(__context, __obj, *args, **kwargs)
if (first_marker := get_first_marker_arg(args, kwargs)) is not None:
return first_marker
try:
with JinjaCallContext(accept_lazy_markers=False):
call_res = super().call(__context, __obj, *lazify_container_args(args), **lazify_container_kwargs(kwargs))
if __obj is range:
# Preserve the ability to do `range(1000000000) | random` by not converting range objects to lists.
# Historically, range objects were only converted on Jinja finalize and filter outputs, so they've always been floating around in templating
# code and visible to user plugins.
return call_res
return _wrap_plugin_output(call_res)
except MarkerError as ex:
return ex.source
AnsibleTemplate.environment_class = AnsibleEnvironment
_DEFAULT_UNDEF = UndefinedMarker("Mandatory variable has not been overridden", _no_template_source=True)
_sentinel: t.Final[object] = object()
@_DirectCall.mark
def _undef(hint=None):
"""Jinja2 global function (undef) for creating getting a `UndefinedMarker` instance, optionally with a custom hint."""
validate_arg_type('hint', hint, (str, type(None)))
if not hint:
return _DEFAULT_UNDEF
return UndefinedMarker(hint)
def _flatten_nodes(nodes: t.Iterable[t.Any]) -> t.Iterable[t.Any]:
"""
Yield nodes from a potentially recursive iterable of nodes.
The recursion is required to expand template imports (TemplateModule).
Any exception raised while consuming a template node will be yielded as a Marker for that node.
"""
iterator = iter(nodes)
while True:
try:
node = next(iterator)
except StopIteration:
break
except Exception as ex:
yield defer_template_error(ex, TemplateContext.current().template_value, is_expression=False)
# DTFIX-FUTURE: We should be able to determine if truncation occurred by having the code generator smuggle out the number of expected nodes.
yield TruncationMarker()
else:
if type(node) is TemplateModule: # pylint: disable=unidiomatic-typecheck
yield from _flatten_nodes(node._body_stream)
else:
yield node
def _flatten_and_lazify_vars(mapping: c.Mapping) -> t.Iterable[c.Mapping]:
"""Prevent deeply-nested Jinja vars ChainMaps from being created by nested contexts and ensure that all top-level containers support lazy templating."""
mapping_type = type(mapping)
if mapping_type is ChainMap:
# noinspection PyUnresolvedReferences
for m in mapping.maps:
yield from _flatten_and_lazify_vars(m)
elif mapping_type is _AnsibleLazyTemplateDict:
if not mapping:
# DTFIX-RELEASE: handle or remove?
raise Exception("we didn't think it was possible to have an empty lazy here...")
yield mapping
elif mapping_type in (dict, _AnsibleTaggedDict):
# don't propagate empty dictionary layers
if mapping:
yield _AnsibleLazyTemplateMixin._try_create(mapping)
else:
raise NotImplementedError(f"unsupported mapping type in Jinja vars: {mapping_type}")
def _new_context(
*,
environment: Environment,
template_name: str | None,
blocks: dict[str, t.Callable[[Context], c.Iterator[str]]],
shared: bool = False,
jinja_locals: c.Mapping[str, t.Any] | None = None,
jinja_vars: c.Mapping[str, t.Any] | None = None,
jinja_globals: c.MutableMapping[str, t.Any] | None = None,
) -> Context:
"""Override Jinja's context vars setup to use ChainMaps and containers that support lazy templating."""
layers = []
if jinja_locals:
# DTFIX-RELEASE: if we can't trip this in coverage, kill it off?
if type(jinja_locals) is not dict: # pylint: disable=unidiomatic-typecheck
raise NotImplementedError("locals must be a dict")
# Omit values set to Jinja's internal `missing` sentinel; they are locals that have not yet been
# initialized in the current context, and should not be exposed to child contexts. e.g.: {% import 'a' as b with context %}.
# The `b` local will be `missing` in the `a` context and should not be propagated as a local to the child context we're creating.
layers.append(_AnsibleLazyTemplateMixin._try_create({k: v for k, v in jinja_locals.items() if v is not missing}))
if jinja_vars:
layers.extend(_flatten_and_lazify_vars(jinja_vars))
if jinja_globals and not shared:
# Even though we don't currently support templating globals, it's easier to ensure that everything is template-able rather than trying to
# pick apart the ChainMaps to enforce non-template-able globals, or to risk things that *should* be template-able not being lazified.
layers.extend(_flatten_and_lazify_vars(jinja_globals))
if not layers:
# ensure we have at least one layer (which should be lazy), since _flatten_and_lazify_vars eliminates most empty layers
layers.append(_AnsibleLazyTemplateMixin._try_create({}))
# only return a ChainMap if we're combining layers, or we have none
parent = layers[0] if len(layers) == 1 else ChainMap(*layers)
# the `parent` cast is only to satisfy Jinja's overly-strict type hint
return environment.context_class(environment, t.cast(dict, parent), template_name, blocks, globals=jinja_globals)
def is_possibly_template(value: str, overrides: TemplateOverrides = TemplateOverrides.DEFAULT):
"""
A lightweight check to determine if the given string looks like it contains a template, even if that template is invalid.
Returns `True` if the given string starts with a Jinja overrides header or if it contains template start strings.
"""
return value.startswith(JINJA2_OVERRIDE) or overrides._contains_start_string(value)
def is_possibly_all_template(value: str, overrides: TemplateOverrides = TemplateOverrides.DEFAULT):
"""
A lightweight check to determine if the given string looks like it contains *only* a template, even if that template is invalid.
Returns `True` if the given string starts with a Jinja overrides header or if it starts and ends with Jinja template delimiters.
"""
return value.startswith(JINJA2_OVERRIDE) or overrides._starts_and_ends_with_jinja_delimiters(value)
class FinalizeMode(enum.Enum):
TOP_LEVEL = enum.auto()
CONCAT = enum.auto()
_FINALIZE_FAST_PATH_EXACT_MAPPING_TYPES = frozenset(
(
dict,
_AnsibleTaggedDict,
_AnsibleLazyTemplateDict,
HostVars,
HostVarsVars,
)
)
"""Fast-path exact mapping types for finalization. These types bypass diagnostic warnings for type conversion."""
_FINALIZE_FAST_PATH_EXACT_ITERABLE_TYPES = frozenset(
(
list,
_AnsibleTaggedList,
_AnsibleLazyTemplateList,
tuple,
_AnsibleTaggedTuple,
_AnsibleLazyAccessTuple,
)
)
"""Fast-path exact iterable types for finalization. These types bypass diagnostic warnings for type conversion."""
_FINALIZE_DISALLOWED_EXACT_TYPES = frozenset((range,))
"""Exact types that cannot be finalized."""
# Jinja passes these into filters/tests via @pass_environment
register_known_types(
AnsibleContext,
AnsibleEnvironment,
EvalContext,
)
def _finalize_dict(o: t.Any, mode: FinalizeMode) -> t.Iterator[tuple[t.Any, t.Any]]:
for k, v in o.items():
if v is not Omit:
yield _finalize_template_result(k, mode), _finalize_template_result(v, mode)
def _finalize_list(o: t.Any, mode: FinalizeMode) -> t.Iterator[t.Any]:
for v in o:
if v is not Omit:
yield _finalize_template_result(v, mode)
def _maybe_finalize_scalar(o: t.Any) -> t.Any:
# DTFIX-RELEASE: this should check all supported scalar subclasses, not just JSON ones (also, does the JSON serializer handle these cases?)
for target_type in _json_subclassable_scalar_types:
if not isinstance(o, target_type):
continue
match _TemplateConfig.unknown_type_conversion_handler.action:
# we don't want to show the object value, and it can't be Origin-tagged; send the current template value for best effort
case ErrorAction.WARNING:
display.warning(
msg=f'Type {native_type_name(o)!r} is unsupported in variable storage, converting to {native_type_name(target_type)!r}.',
obj=TemplateContext.current(optional=True).template_value,
)
case ErrorAction.ERROR:
raise AnsibleVariableTypeError.from_value(obj=TemplateContext.current(optional=True).template_value)
return target_type(o)
return None
def _finalize_fallback_collection(
o: t.Any,
mode: FinalizeMode,
finalizer: t.Callable[[t.Any, FinalizeMode], t.Iterator],
target_type: type[list | dict],
) -> t.Collection[t.Any]:
match _TemplateConfig.unknown_type_conversion_handler.action:
# we don't want to show the object value, and it can't be Origin-tagged; send the current template value for best effort
case ErrorAction.WARNING:
display.warning(
msg=f'Type {native_type_name(o)!r} is unsupported in variable storage, converting to {native_type_name(target_type)!r}.',
obj=TemplateContext.current(optional=True).template_value,
)
case ErrorAction.ERROR:
raise AnsibleVariableTypeError.from_value(obj=TemplateContext.current(optional=True).template_value)
return _finalize_collection(o, mode, finalizer, target_type)
def _finalize_collection(
o: t.Any,
mode: FinalizeMode,
finalizer: t.Callable[[t.Any, FinalizeMode], t.Iterator],
target_type: type[list | dict],
) -> t.Collection[t.Any]:
return AnsibleTagHelper.tag(finalizer(o, mode), AnsibleTagHelper.tags(o), value_type=target_type)
def _finalize_template_result(o: t.Any, mode: FinalizeMode) -> t.Any:
"""Recurse the template result, rendering any encountered templates, converting containers to non-lazy versions."""
# DTFIX-RELEASE: add tests to ensure this method doesn't drift from allowed types
o_type = type(o)
# DTFIX-FUTURE: provide an optional way to check for trusted templates leaking out of templating (injected, but not passed through templar.template)
if o_type is _AnsibleTaggedStr:
return _JinjaConstTemplate.untag(o) # prevent _JinjaConstTemplate from leaking into finalized results
if o_type in PASS_THROUGH_SCALAR_VAR_TYPES:
return o
if o_type in _FINALIZE_FAST_PATH_EXACT_MAPPING_TYPES: # silently convert known mapping types to dict
return _finalize_collection(o, mode, _finalize_dict, dict)
if o_type in _FINALIZE_FAST_PATH_EXACT_ITERABLE_TYPES: # silently convert known sequence types to list
return _finalize_collection(o, mode, _finalize_list, list)
if o_type in Marker.concrete_subclasses: # this early return assumes handle_marker follows our variable type rules
return TemplateContext.current().templar.marker_behavior.handle_marker(o)
if mode is not FinalizeMode.TOP_LEVEL: # unsupported type (do not raise)
return o
if o_type in _FINALIZE_DISALLOWED_EXACT_TYPES: # early abort for disallowed types that would otherwise be handled below
raise AnsibleVariableTypeError.from_value(obj=o)
if _internal.is_intermediate_mapping(o): # since isinstance checks are slower, this is separate from the exact type check above
return _finalize_fallback_collection(o, mode, _finalize_dict, dict)
if _internal.is_intermediate_iterable(o): # since isinstance checks are slower, this is separate from the exact type check above
return _finalize_fallback_collection(o, mode, _finalize_list, list)
if (result := _maybe_finalize_scalar(o)) is not None:
return result
raise AnsibleVariableTypeError.from_value(obj=o)
ansible_core-2.19.0b4/lib/ansible/_internal/_templating/_jinja_common.py 0000644 0000000 0000000 00000030033 15010426755 025035 0 ustar 00root root from __future__ import annotations
import abc
import collections.abc as c
import inspect
import itertools
import typing as t
from jinja2 import UndefinedError, StrictUndefined, TemplateRuntimeError
from jinja2.utils import missing
from ansible.module_utils.common.messages import ErrorSummary, Detail
from ansible.constants import config
from ansible.errors import AnsibleUndefinedVariable, AnsibleTypeError
from ansible._internal._errors._handler import ErrorHandler
from ansible.module_utils._internal._datatag import Tripwire, _untaggable_types
from ._access import NotifiableAccessContextBase
from ._jinja_patches import _patch_jinja
from ._utils import TemplateContext
from .._errors import _captured
from ...module_utils.datatag import native_type_name
_patch_jinja() # apply Jinja2 patches before types are declared that are dependent on the changes
class _TemplateConfig:
allow_embedded_templates: bool = config.get_config_value("ALLOW_EMBEDDED_TEMPLATES")
allow_broken_conditionals: bool = config.get_config_value('ALLOW_BROKEN_CONDITIONALS')
jinja_extensions: list[str] = config.get_config_value('DEFAULT_JINJA2_EXTENSIONS')
unknown_type_encountered_handler = ErrorHandler.from_config('_TEMPLAR_UNKNOWN_TYPE_ENCOUNTERED')
unknown_type_conversion_handler = ErrorHandler.from_config('_TEMPLAR_UNKNOWN_TYPE_CONVERSION')
untrusted_template_handler = ErrorHandler.from_config('_TEMPLAR_UNTRUSTED_TEMPLATE_BEHAVIOR')
class MarkerError(UndefinedError):
"""
An Ansible specific subclass of Jinja's UndefinedError, used to preserve and later restore the original Marker instance that raised the error.
This error is only raised by Marker and should never escape the templating system.
"""
def __init__(self, message: str, source: Marker) -> None:
super().__init__(message)
self.source = source
class Marker(StrictUndefined, Tripwire):
"""
Extends Jinja's `StrictUndefined`, allowing any kind of error occurring during recursive templating operations to be captured and deferred.
Direct or managed access to most `Marker` attributes will raise a `MarkerError`, which usually ends the current innermost templating
operation and converts the `MarkerError` back to the origin Marker instance (subject to the `MarkerBehavior` in effect at the time).
"""
__slots__ = ('_marker_template_source',)
concrete_subclasses: t.ClassVar[set[type[Marker]]] = set()
def __init__(
self,
hint: t.Optional[str] = None,
obj: t.Any = missing,
name: t.Optional[str] = None,
exc: t.Type[TemplateRuntimeError] = UndefinedError, # Ansible doesn't set this argument or consume the attribute it is stored under.
*args,
_no_template_source=False,
**kwargs,
) -> None:
if not hint and name and obj is not missing:
hint = f"object of type {native_type_name(obj)!r} has no attribute {name!r}"
kwargs.update(
hint=hint,
obj=obj,
name=name,
exc=exc,
)
super().__init__(*args, **kwargs)
if _no_template_source:
self._marker_template_source = None
else:
self._marker_template_source = TemplateContext.current().template_value
def _as_exception(self) -> Exception:
"""Return the exception instance to raise in a top-level templating context."""
return AnsibleUndefinedVariable(self._undefined_message, obj=self._marker_template_source)
def _as_message(self) -> str:
"""Return the error message to show when this marker must be represented as a string, such as for subsitutions or warnings."""
return self._undefined_message
def _fail_with_undefined_error(self, *args: t.Any, **kwargs: t.Any) -> t.NoReturn:
"""Ansible-specific replacement for Jinja's _fail_with_undefined_error tripwire on dunder methods."""
self.trip()
def trip(self) -> t.NoReturn:
"""Raise an internal exception which can be converted back to this instance."""
raise MarkerError(self._undefined_message, self)
def __setattr__(self, name: str, value: t.Any) -> None:
"""
Any attempt to set an unknown attribute on a `Marker` should invoke the trip method to propagate the original context.
This does not protect against mutation of known attributes, but the implementation is fairly simple.
"""
try:
super().__setattr__(name, value)
except AttributeError:
pass
else:
return
self.trip()
def __getattr__(self, name: str) -> t.Any:
"""Raises AttributeError for dunder-looking accesses, self-propagates otherwise."""
if name.startswith('__') and name.endswith('__'):
raise AttributeError(name)
return self
def __getitem__(self, key):
"""Self-propagates on all item accesses."""
return self
@classmethod
def __init_subclass__(cls, **kwargs) -> None:
if not inspect.isabstract(cls):
_untaggable_types.add(cls)
cls.concrete_subclasses.add(cls)
@classmethod
def _init_class(cls):
_untaggable_types.add(cls)
# These are the methods StrictUndefined already intercepts.
jinja_method_names = (
'__add__',
'__bool__',
'__call__',
'__complex__',
'__contains__',
'__div__',
'__eq__',
'__float__',
'__floordiv__',
'__ge__',
# '__getitem__', # using a custom implementation that propagates self instead
'__gt__',
'__hash__',
'__int__',
'__iter__',
'__le__',
'__len__',
'__lt__',
'__mod__',
'__mul__',
'__ne__',
'__neg__',
'__pos__',
'__pow__',
'__radd__',
'__rdiv__',
'__rfloordiv__',
'__rmod__',
'__rmul__',
'__rpow__',
'__rsub__',
'__rtruediv__',
'__str__',
'__sub__',
'__truediv__',
)
# These additional methods should be intercepted, even though they are not intercepted by StrictUndefined.
additional_method_names = (
'__aiter__',
'__delattr__',
'__format__',
'__repr__',
'__setitem__',
)
for name in jinja_method_names + additional_method_names:
setattr(cls, name, cls._fail_with_undefined_error)
Marker._init_class()
class TruncationMarker(Marker):
"""
An `Marker` value was previously encountered and reported.
A subsequent `Marker` value (this instance) indicates the template may have been truncated as a result.
It will only be visible if the previous `Marker` was ignored/replaced instead of being tripped, which would raise an exception.
"""
# DTFIX-RELEASE: make this a singleton?
__slots__ = ()
def __init__(self) -> None:
super().__init__(hint='template potentially truncated')
class UndefinedMarker(Marker):
"""A `Marker` value that represents an undefined value encountered during templating."""
__slots__ = ()
class ExceptionMarker(Marker, metaclass=abc.ABCMeta):
"""Base `Marker` class that represents exceptions encountered and deferred during templating."""
__slots__ = ()
@abc.abstractmethod
def _as_exception(self) -> Exception:
pass
def _as_message(self) -> str:
return str(self._as_exception())
def trip(self) -> t.NoReturn:
"""Raise an internal exception which can be converted back to this instance while maintaining the cause for callers that follow them."""
raise MarkerError(self._undefined_message, self) from self._as_exception()
class CapturedExceptionMarker(ExceptionMarker):
"""A `Marker` value that represents an exception raised during templating."""
__slots__ = ('_marker_captured_exception',)
def __init__(self, exception: Exception) -> None:
super().__init__(hint=f'A captured exception marker was tripped: {exception}')
self._marker_captured_exception = exception
def _as_exception(self) -> Exception:
return self._marker_captured_exception
class UndecryptableVaultError(_captured.AnsibleCapturedError):
"""Template-external error raised by VaultExceptionMarker when an undecryptable variable is accessed."""
context = 'vault'
_default_message = "Attempt to use undecryptable variable."
class VaultExceptionMarker(ExceptionMarker):
"""A `Marker` value that represents an error accessing a vaulted value during templating."""
__slots__ = ('_marker_undecryptable_ciphertext', '_marker_undecryptable_reason', '_marker_undecryptable_traceback')
def __init__(self, ciphertext: str, reason: str, traceback: str | None) -> None:
# DTFIX-RELEASE: when does this show up, should it contain more details?
# see also CapturedExceptionMarker for a similar issue
super().__init__(hint='A vault exception marker was tripped.')
self._marker_undecryptable_ciphertext = ciphertext
self._marker_undecryptable_reason = reason
self._marker_undecryptable_traceback = traceback
def _as_exception(self) -> Exception:
return UndecryptableVaultError(
obj=self._marker_undecryptable_ciphertext,
error_summary=ErrorSummary(
details=(
Detail(
msg=self._marker_undecryptable_reason,
),
),
formatted_traceback=self._marker_undecryptable_traceback,
),
)
def _disarm(self) -> str:
return self._marker_undecryptable_ciphertext
def get_first_marker_arg(args: c.Sequence, kwargs: dict[str, t.Any]) -> Marker | None:
"""Utility method to inspect plugin args and return the first `Marker` encountered, otherwise `None`."""
# DTFIX-RELEASE: this may or may not need to be public API, move back to utils or once usage is wrapped in a decorator?
for arg in iter_marker_args(args, kwargs):
return arg
return None
def iter_marker_args(args: c.Sequence, kwargs: dict[str, t.Any]) -> t.Generator[Marker]:
"""Utility method to iterate plugin args and yield any `Marker` encountered."""
# DTFIX-RELEASE: this may or may not need to be public API, move back to utils or once usage is wrapped in a decorator?
for arg in itertools.chain(args, kwargs.values()):
if isinstance(arg, Marker):
yield arg
class JinjaCallContext(NotifiableAccessContextBase):
"""
An audit context that wraps all Jinja (template/filter/test/lookup/method/function) calls.
While active, calls `trip()` on managed access of `Marker` objects unless the callee declares an understanding of markers.
"""
_mask = True
def __init__(self, accept_lazy_markers: bool) -> None:
self._type_interest = frozenset() if accept_lazy_markers else frozenset(Marker.concrete_subclasses)
def _notify(self, o: Marker) -> t.NoReturn:
o.trip()
def validate_arg_type(name: str, value: t.Any, allowed_type_or_types: type | tuple[type, ...], /) -> None:
"""Validate the type of the given argument while preserving context for Marker values."""
# DTFIX-RELEASE: find a home for this as a general-purpose utliity method and expose it after some API review
if isinstance(value, allowed_type_or_types):
return
if isinstance(allowed_type_or_types, type):
arg_type_description = repr(native_type_name(allowed_type_or_types))
else:
arg_type_description = ' or '.join(repr(native_type_name(item)) for item in allowed_type_or_types)
if isinstance(value, Marker):
try:
value.trip()
except Exception as ex:
raise AnsibleTypeError(f"The {name!r} argument must be of type {arg_type_description}.", obj=value) from ex
raise AnsibleTypeError(f"The {name!r} argument must be of type {arg_type_description}, not {native_type_name(value)!r}.", obj=value)
ansible_core-2.19.0b4/lib/ansible/_internal/_templating/_jinja_patches.py 0000644 0000000 0000000 00000002604 15010426755 025177 0 ustar 00root root """Runtime patches for Jinja bugs affecting Ansible."""
from __future__ import annotations
import jinja2
import jinja2.utils
def _patch_jinja_undefined_slots() -> None:
"""
Fix the broken __slots__ on Jinja's Undefined and StrictUndefined if they're missing in the current version.
This will no longer be necessary once the fix is included in the minimum supported Jinja version.
See: https://github.com/pallets/jinja/issues/2025
"""
if not hasattr(jinja2.Undefined, '__slots__'):
jinja2.Undefined.__slots__ = (
"_undefined_hint",
"_undefined_obj",
"_undefined_name",
"_undefined_exception",
)
if not hasattr(jinja2.StrictUndefined, '__slots__'):
jinja2.StrictUndefined.__slots__ = ()
def _patch_jinja_missing_type() -> None:
"""
Fix the `jinja2.utils.missing` type to support pickling while remaining a singleton.
This will no longer be necessary once the fix is included in the minimum supported Jinja version.
See: https://github.com/pallets/jinja/issues/2027
"""
if getattr(jinja2.utils.missing, '__reduce__')() != 'missing':
def __reduce__(*_args):
return 'missing'
type(jinja2.utils.missing).__reduce__ = __reduce__
def _patch_jinja() -> None:
"""Apply Jinja2 patches."""
_patch_jinja_undefined_slots()
_patch_jinja_missing_type()
ansible_core-2.19.0b4/lib/ansible/_internal/_templating/_jinja_plugins.py 0000644 0000000 0000000 00000035470 15010426755 025240 0 ustar 00root root """Jinja template plugins (filters, tests, lookups) and custom global functions."""
from __future__ import annotations
import collections.abc as c
import dataclasses
import datetime
import functools
import typing as t
from ansible.module_utils._internal._ambient_context import AmbientContextBase
from ansible.module_utils.common.collections import is_sequence
from ansible.module_utils._internal._datatag import AnsibleTagHelper
from ansible._internal._datatag._tags import TrustedAsTemplate
from ansible.plugins import AnsibleJinja2Plugin
from ansible.plugins.loader import lookup_loader, Jinja2Loader
from ansible.plugins.lookup import LookupBase
from ansible.utils.display import Display
from ._datatag import _JinjaConstTemplate
from ._errors import AnsibleTemplatePluginRuntimeError, AnsibleTemplatePluginLoadError, AnsibleTemplatePluginNotFoundError
from ._jinja_common import MarkerError, _TemplateConfig, get_first_marker_arg, Marker, JinjaCallContext
from ._lazy_containers import lazify_container_kwargs, lazify_container_args, lazify_container, _AnsibleLazyTemplateMixin
from ._utils import LazyOptions, TemplateContext
_display = Display()
_TCallable = t.TypeVar("_TCallable", bound=t.Callable)
_ITERATOR_TYPES: t.Final = (c.Iterator, c.ItemsView, c.KeysView, c.ValuesView, range)
class JinjaPluginIntercept(c.MutableMapping):
"""
Simulated dict class that loads Jinja2Plugins at request
otherwise all plugins would need to be loaded a priori.
NOTE: plugin_loader still loads all 'builtin/legacy' at
start so only collection plugins are really at request.
"""
def __init__(self, jinja_builtins: c.Mapping[str, AnsibleJinja2Plugin], plugin_loader: Jinja2Loader):
super(JinjaPluginIntercept, self).__init__()
self._plugin_loader = plugin_loader
self._jinja_builtins = jinja_builtins
self._wrapped_funcs: dict[str, t.Callable] = {}
def _wrap_and_set_func(self, instance: AnsibleJinja2Plugin) -> t.Callable:
if self._plugin_loader.type == 'filter':
plugin_func = self._wrap_filter(instance)
else:
plugin_func = self._wrap_test(instance)
self._wrapped_funcs[instance._load_name] = plugin_func
return plugin_func
def __getitem__(self, key: str) -> t.Callable:
instance: AnsibleJinja2Plugin | None = None
plugin_func: t.Callable[..., t.Any] | None
if plugin_func := self._wrapped_funcs.get(key):
return plugin_func
try:
instance = self._plugin_loader.get(key)
except KeyError:
# The plugin name was invalid or no plugin was found by that name.
pass
except Exception as ex:
# An unexpected exception occurred.
raise AnsibleTemplatePluginLoadError(self._plugin_loader.type, key) from ex
if not instance:
try:
instance = self._jinja_builtins[key]
except KeyError:
raise AnsibleTemplatePluginNotFoundError(self._plugin_loader.type, key) from None
plugin_func = self._wrap_and_set_func(instance)
return plugin_func
def __setitem__(self, key: str, value: t.Callable) -> None:
self._wrap_and_set_func(self._plugin_loader._wrap_func(key, key, value))
def __delitem__(self, key):
raise NotImplementedError()
def __contains__(self, item: t.Any) -> bool:
try:
self.__getitem__(item)
except AnsibleTemplatePluginLoadError:
return True
except AnsibleTemplatePluginNotFoundError:
return False
return True
def __iter__(self):
raise NotImplementedError() # dynamic container
def __len__(self):
raise NotImplementedError() # dynamic container
@staticmethod
def _invoke_plugin(instance: AnsibleJinja2Plugin, *args, **kwargs) -> t.Any:
if not instance.accept_args_markers:
if (first_marker := get_first_marker_arg(args, kwargs)) is not None:
return first_marker
try:
with JinjaCallContext(accept_lazy_markers=instance.accept_lazy_markers):
return instance.j2_function(*lazify_container_args(args), **lazify_container_kwargs(kwargs))
except MarkerError as ex:
return ex.source
except Exception as ex:
raise AnsibleTemplatePluginRuntimeError(instance.plugin_type, instance.ansible_name) from ex # DTFIX-RELEASE: which name to use? use plugin info?
def _wrap_test(self, instance: AnsibleJinja2Plugin) -> t.Callable:
"""Intercept point for all test plugins to ensure that args are properly templated/lazified."""
@functools.wraps(instance.j2_function)
def wrapper(*args, **kwargs) -> bool | Marker:
result = self._invoke_plugin(instance, *args, **kwargs)
if not isinstance(result, bool):
template = TemplateContext.current().template_value
# DTFIX-RELEASE: which name to use? use plugin info?
_display.deprecated(
msg=f"The test plugin {instance.ansible_name!r} returned a non-boolean result of type {type(result)!r}. "
"Test plugins must have a boolean result.",
obj=template,
version="2.23",
)
result = bool(result)
return result
return wrapper
def _wrap_filter(self, instance: AnsibleJinja2Plugin) -> t.Callable:
"""Intercept point for all filter plugins to ensure that args are properly templated/lazified."""
@functools.wraps(instance.j2_function)
def wrapper(*args, **kwargs) -> t.Any:
result = self._invoke_plugin(instance, *args, **kwargs)
result = _wrap_plugin_output(result)
return result
return wrapper
class _DirectCall:
"""Functions/methods marked `_DirectCall` bypass Jinja Environment checks for `Marker`."""
_marker_attr: str = "_directcall"
@classmethod
def mark(cls, src: _TCallable) -> _TCallable:
setattr(src, cls._marker_attr, True)
return src
@classmethod
def is_marked(cls, value: t.Callable) -> bool:
return callable(value) and getattr(value, "_directcall", False)
@_DirectCall.mark
def _query(plugin_name: str, /, *args, **kwargs) -> t.Any:
"""wrapper for lookup, force wantlist true"""
kwargs['wantlist'] = True
return _invoke_lookup(plugin_name=plugin_name, lookup_terms=list(args), lookup_kwargs=kwargs)
@_DirectCall.mark
def _lookup(plugin_name: str, /, *args, **kwargs) -> t.Any:
# convert the args tuple to a list, since some plugins make a poor assumption that `run.args` is a list
return _invoke_lookup(plugin_name=plugin_name, lookup_terms=list(args), lookup_kwargs=kwargs)
@dataclasses.dataclass
class _LookupContext(AmbientContextBase):
"""Ambient context that wraps lookup execution, providing information about how it was invoked."""
invoked_as_with: bool
@_DirectCall.mark
def _invoke_lookup(*, plugin_name: str, lookup_terms: list, lookup_kwargs: dict[str, t.Any], invoked_as_with: bool = False) -> t.Any:
templar = TemplateContext.current().templar
from ansible import template as _template
try:
instance: LookupBase | None = lookup_loader.get(plugin_name, loader=templar._loader, templar=_template.Templar._from_template_engine(templar))
except Exception as ex:
raise AnsibleTemplatePluginLoadError('lookup', plugin_name) from ex
if instance is None:
raise AnsibleTemplatePluginNotFoundError('lookup', plugin_name)
# if the lookup doesn't understand `Marker` and there's at least one in the top level, short-circuit by returning the first one we found
if not instance.accept_args_markers and (first_marker := get_first_marker_arg(lookup_terms, lookup_kwargs)) is not None:
return first_marker
# don't pass these through to the lookup
wantlist = lookup_kwargs.pop('wantlist', False)
errors = lookup_kwargs.pop('errors', 'strict')
with JinjaCallContext(accept_lazy_markers=instance.accept_lazy_markers):
try:
if _TemplateConfig.allow_embedded_templates:
# for backwards compat, only trust constant templates in lookup terms
with JinjaCallContext(accept_lazy_markers=True):
# Force lazy marker support on for this call; the plugin's understanding is irrelevant, as is any existing context, since this backward
# compat code always understands markers.
lookup_terms = [templar.template(value) for value in _trust_jinja_constants(lookup_terms)]
# since embedded template support is enabled, repeat the check for `Marker` on lookup_terms, since a template may render as a `Marker`
if not instance.accept_args_markers and (first_marker := get_first_marker_arg(lookup_terms, {})) is not None:
return first_marker
else:
lookup_terms = AnsibleTagHelper.tag_copy(lookup_terms, (lazify_container(value) for value in lookup_terms), value_type=list)
with _LookupContext(invoked_as_with=invoked_as_with):
# The lookup context currently only supports the internal use-case where `first_found` requires extra info when invoked via `with_first_found`.
# The context may be public API in the future, but for now, other plugins should not implement this kind of dynamic behavior,
# though we're stuck with it for backward compatibility on `first_found`.
lookup_res = instance.run(lookup_terms, variables=templar.available_variables, **lazify_container_kwargs(lookup_kwargs))
# DTFIX-FUTURE: Consider allowing/requiring lookup plugins to declare how their result should be handled.
# Currently, there are multiple behaviors that are less than ideal and poorly documented (or not at all):
# * When `errors=warn` or `errors=ignore` the result is `None` unless `wantlist=True`, in which case the result is `[]`.
# * The user must specify `wantlist=True` to receive the plugin return value unmodified.
# A plugin can achieve similar results by wrapping its result in a list -- unless of course the user specifies `wantlist=True`.
# * When `wantlist=True` is specified, the result is not guaranteed to be a list as the option implies (except on plugin error).
# * Sequences are munged unless the user specifies `wantlist=True`:
# * len() == 0 - Return an empty sequence.
# * len() == 1 - Return the only element in the sequence.
# * len() >= 2 when all elements are `str` - Return all the values joined into a single comma separated string.
# * len() >= 2 when at least one element is not `str` - Return the sequence as-is.
if not is_sequence(lookup_res):
# DTFIX-FUTURE: deprecate return types which are not a list
# previously non-Sequence return types were deprecated and then became an error in 2.18
# however, the deprecation message (and this error) mention `list` specifically rather than `Sequence`
# letting non-list values through will trigger variable type checking warnings/errors
raise TypeError(f'returned {type(lookup_res)} instead of {list}')
except MarkerError as ex:
return ex.source
except Exception as ex:
# DTFIX-RELEASE: convert this to the new error/warn/ignore context manager
if errors == 'warn':
_display.error_as_warning(
msg=f'An error occurred while running the lookup plugin {plugin_name!r}.',
exception=ex,
)
elif errors == 'ignore':
_display.display(f'An error of type {type(ex)} occurred while running the lookup plugin {plugin_name!r}: {ex}', log_only=True)
else:
raise AnsibleTemplatePluginRuntimeError('lookup', plugin_name) from ex
return [] if wantlist else None
if not wantlist and lookup_res:
# when wantlist=False the lookup result is either partially delaizified (single element) or fully delaizified (multiple elements)
if len(lookup_res) == 1:
lookup_res = lookup_res[0]
else:
try:
lookup_res = ",".join(lookup_res) # for backwards compatibility, attempt to join `ran` into single string
except TypeError:
pass # for backwards compatibility, return `ran` as-is when the sequence contains non-string values
return _wrap_plugin_output(lookup_res)
def _now(utc=False, fmt=None):
"""Jinja2 global function (now) to return current datetime, potentially formatted via strftime."""
if utc:
now = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
else:
now = datetime.datetime.now()
if fmt:
return now.strftime(fmt)
return now
def _jinja_const_template_warning(value: object, is_conditional: bool) -> None:
"""Issue a warning regarding embedded template usage."""
help_text = "Use inline expressions, for example: "
if is_conditional:
help_text += """`when: "{{ a_var }}" == 42` becomes `when: a_var == 42`"""
else:
help_text += """`msg: "{{ lookup('env', '{{ a_var }}') }}"` becomes `msg: "{{ lookup('env', a_var) }}"`"""
# deprecated: description='disable embedded templates by default and deprecate the feature' core_version='2.23'
_display.warning(
msg="Jinja constant strings should not contain embedded templates. This feature will be disabled by default in ansible-core 2.23.",
obj=value,
help_text=help_text,
)
def _trust_jinja_constants(o: t.Any) -> t.Any:
"""
Recursively apply TrustedAsTemplate to values tagged with _JinjaConstTemplate and remove the tag.
Only container types emitted by the Jinja compiler are checked, since others do not contain constants.
This is used to provide backwards compatibility with historical lookup behavior for positional arguments.
"""
if _JinjaConstTemplate.is_tagged_on(o):
_jinja_const_template_warning(o, is_conditional=False)
return TrustedAsTemplate().tag(_JinjaConstTemplate.untag(o))
o_type = type(o)
if o_type is dict:
return {k: _trust_jinja_constants(v) for k, v in o.items()}
if o_type in (list, tuple):
return o_type(_trust_jinja_constants(v) for v in o)
return o
def _wrap_plugin_output(o: t.Any) -> t.Any:
"""Utility method to ensure that iterators/generators returned from a plugins are consumed."""
if isinstance(o, _ITERATOR_TYPES):
o = list(o)
return _AnsibleLazyTemplateMixin._try_create(o, LazyOptions.SKIP_TEMPLATES)
ansible_core-2.19.0b4/lib/ansible/_internal/_templating/_lazy_containers.py 0000644 0000000 0000000 00000065040 15010426755 025604 0 ustar 00root root from __future__ import annotations
import copy
import dataclasses
import functools
import types
import typing as t
from jinja2.environment import TemplateModule
from ansible.module_utils._internal._datatag import (
AnsibleTagHelper,
AnsibleTaggedObject,
_AnsibleTaggedDict,
_AnsibleTaggedList,
_AnsibleTaggedTuple,
_NO_INSTANCE_STORAGE,
_try_get_internal_tags_mapping,
)
from ansible.utils.sentinel import Sentinel
from ansible.errors import AnsibleVariableTypeError
from ansible._internal._errors._handler import Skippable
from ansible.vars.hostvars import HostVarsVars, HostVars
from ._access import AnsibleAccessContext
from ._jinja_common import Marker, _TemplateConfig
from ._utils import TemplateContext, PASS_THROUGH_SCALAR_VAR_TYPES, LazyOptions
if t.TYPE_CHECKING:
from ._engine import TemplateEngine
_KNOWN_TYPES: t.Final[set[type]] = (
{
HostVars, # example: hostvars
HostVarsVars, # example: hostvars.localhost | select
type, # example: range(20) | list # triggered on retrieval of `range` type from globals
range, # example: range(20) | list # triggered when returning a `range` instance from a call
types.FunctionType, # example: undef() | default("blah")
types.MethodType, # example: ansible_facts.get | type_debug
functools.partial,
type(''.startswith), # example: inventory_hostname.upper | type_debug # using `startswith` to resolve `builtin_function_or_method`
TemplateModule, # example: '{% import "importme.j2" as im %}{{ im | type_debug }}'
}
| set(PASS_THROUGH_SCALAR_VAR_TYPES)
| set(Marker.concrete_subclasses)
)
"""
These types are known to the templating system.
In addition to the statically defined types, additional types will be added at runtime.
When enabled in config, this set will be used to determine if an encountered type should trigger a warning or error.
"""
def register_known_types(*args: type) -> None:
"""Register a type with the template engine so it will not trigger warnings or errors when encountered."""
_KNOWN_TYPES.update(args)
class UnsupportedConstructionMethodError(RuntimeError):
"""Error raised when attempting to construct a lazy container with unsupported arguments."""
def __init__(self):
super().__init__("Direct construction of lazy containers is not supported.")
@t.final
@dataclasses.dataclass(frozen=True, slots=True)
class _LazyValue:
"""Wrapper around values to indicate lazy behavior has not yet been applied."""
value: t.Any
@t.final
@dataclasses.dataclass(frozen=True, kw_only=True, slots=True)
class _LazyValueSource:
"""Intermediate value source for lazy-eligible collection copy operations."""
source: t.Iterable
templar: TemplateEngine
lazy_options: LazyOptions
@t.final
class _NoKeySentinel(Sentinel):
"""Sentinel used to indicate a requested key was not found."""
# There are several operations performed by lazy containers, with some variation between types.
#
# Columns: D=dict, L=list, T=tuple
# Cells: l=lazy (upon access), n=non-lazy (__init__/__new__)
#
# D L T Feature Description
# - - - ----------- ---------------------------------------------------------------
# l l n propagation when container items which are containers become lazy instances
# l l n transform when transforms are applied to container items
# l l n templating when templating is performed on container items
# l l l access when access calls are performed on container items
class _AnsibleLazyTemplateMixin:
__slots__ = _NO_INSTANCE_STORAGE
_dispatch_types: t.ClassVar[dict[type, type[_AnsibleLazyTemplateMixin]]] = {} # populated by __init_subclass__
_container_types: t.ClassVar[set[type]] = set() # populated by __init_subclass__
_native_type: t.ClassVar[type] # from AnsibleTaggedObject
_SLOTS: t.Final = (
'_templar',
'_lazy_options',
)
_templar: TemplateEngine
_lazy_options: LazyOptions
def __init_subclass__(cls, **kwargs) -> None:
tagged_type = cls.__mro__[1]
native_type = tagged_type.__mro__[1]
for check_type in (tagged_type, native_type):
if conflicting_type := cls._dispatch_types.get(check_type):
raise TypeError(f"Lazy mixin {cls.__name__!r} type {check_type.__name__!r} conflicts with {conflicting_type.__name__!r}.")
cls._dispatch_types[native_type] = cls
cls._dispatch_types[tagged_type] = cls
cls._container_types.add(native_type)
cls._empty_tags_as_native = False # never revert to the native type when no tags remain
register_known_types(cls)
def __init__(self, contents: t.Iterable | _LazyValueSource) -> None:
if isinstance(contents, _LazyValueSource):
self._templar = contents.templar
self._lazy_options = contents.lazy_options
elif isinstance(contents, _AnsibleLazyTemplateMixin):
self._templar = contents._templar
self._lazy_options = contents._lazy_options
else:
raise UnsupportedConstructionMethodError()
def __reduce_ex__(self, protocol):
raise NotImplementedError("Pickling of Ansible lazy objects is not permitted.")
@staticmethod
def _try_create(item: t.Any, lazy_options: LazyOptions = LazyOptions.DEFAULT) -> t.Any:
"""
If `item` is a container type which supports lazy access and/or templating, return a lazy wrapped version -- otherwise return it as-is.
When returning as-is, a warning or error may be generated for unknown types.
The `lazy_options.skip_templates` argument should be set to `True` when `item` is sourced from a plugin instead of Ansible variable storage.
This provides backwards compatibility and reduces lazy overhead, as plugins do not normally introduce templates.
If a plugin needs to introduce templates, the plugin is responsible for invoking the templar and returning the result.
"""
item_type = type(item)
# Try to use exact type match first to determine which wrapper (if any) to apply; isinstance checks
# are extremely expensive, so try to avoid them for our commonly-supported types.
if (dispatcher := _AnsibleLazyTemplateMixin._dispatch_types.get(item_type)) is not None:
# Create a generator that yields the elements of `item` wrapped in a `_LazyValue` wrapper.
# The wrapper is used to signal to the lazy container that the value must be processed before being returned.
# Values added to the lazy container later through other means will be returned as-is, without any special processing.
lazy_values = dispatcher._lazy_values(item, lazy_options)
tags_mapping = _try_get_internal_tags_mapping(item)
value = t.cast(AnsibleTaggedObject, dispatcher)._instance_factory(lazy_values, tags_mapping)
return value
with Skippable, _TemplateConfig.unknown_type_encountered_handler.handle(AnsibleVariableTypeError, skip_on_ignore=True):
if item_type not in _KNOWN_TYPES:
raise AnsibleVariableTypeError(
message=f"Encountered unknown type {item_type.__name__!r} during template operation.",
help_text="Use supported types to avoid unexpected behavior.",
obj=TemplateContext.current().template_value,
)
return item
def _is_not_lazy_combine_candidate(self, other: object) -> bool:
"""Returns `True` if `other` cannot be lazily combined with the current instance due to differing templar/options, otherwise returns `False`."""
return isinstance(other, _AnsibleLazyTemplateMixin) and (self._templar is not other._templar or self._lazy_options != other._lazy_options)
def _non_lazy_copy(self) -> t.Collection:
"""
Return a non-lazy copy of this collection.
Any remaining lazy wrapped values will be unwrapped without further processing.
Tags on this instance will be preserved on the returned copy.
"""
raise NotImplementedError() # pragma: nocover
@staticmethod
def _lazy_values(values: t.Any, lazy_options: LazyOptions) -> _LazyValueSource:
"""
Return an iterable that wraps each of the given elements in a lazy wrapper.
Only elements wrapped this way will receive lazy processing when retrieved from the collection.
"""
# DTFIX-RELEASE: check relative performance of method-local vs stored generator expressions on implementations of this method
raise NotImplementedError() # pragma: nocover
def _proxy_or_render_lazy_value(self, key: t.Any, value: t.Any) -> t.Any:
"""
Ensure that the value is lazy-proxied or rendered, and if a key is provided, replace the original value with the result.
"""
if type(value) is not _LazyValue: # pylint: disable=unidiomatic-typecheck
if self._lazy_options.access:
AnsibleAccessContext.current().access(value)
return value
original_value = value.value
if self._lazy_options.access:
AnsibleAccessContext.current().access(original_value)
new_value = self._templar.template(original_value, lazy_options=self._lazy_options)
if new_value is not original_value and self._lazy_options.access:
AnsibleAccessContext.current().access(new_value)
if key is not _NoKeySentinel:
self._native_type.__setitem__(self, key, new_value) # type: ignore # pylint: disable=unnecessary-dunder-call
return new_value
@t.final # consumers of lazy collections rely heavily on the concrete types being final
class _AnsibleLazyTemplateDict(_AnsibleTaggedDict, _AnsibleLazyTemplateMixin):
__slots__ = _AnsibleLazyTemplateMixin._SLOTS
def __init__(self, contents: t.Iterable | _LazyValueSource, /, **kwargs) -> None:
_AnsibleLazyTemplateMixin.__init__(self, contents)
if isinstance(contents, _AnsibleLazyTemplateDict):
super().__init__(dict.items(contents), **kwargs)
elif isinstance(contents, _LazyValueSource):
super().__init__(contents.source, **kwargs)
else:
raise UnsupportedConstructionMethodError()
def get(self, key: t.Any, default: t.Any = None) -> t.Any:
if (value := super().get(key, _NoKeySentinel)) is _NoKeySentinel:
return default
return self._proxy_or_render_lazy_value(key, value)
def __getitem__(self, key: t.Any, /) -> t.Any:
return self._proxy_or_render_lazy_value(key, super().__getitem__(key))
def __str__(self):
return str(self.copy()._native_copy()) # inefficient, but avoids mutating the current instance (to make debugging practical)
def __repr__(self):
return repr(self.copy()._native_copy()) # inefficient, but avoids mutating the current instance (to make debugging practical)
def __iter__(self):
# We're using the base implementation, but must override `__iter__` to skip `dict` fast-path copy, which would bypass lazy behavior.
# See: https://github.com/python/cpython/blob/ffcc450a9b8b6927549b501eff7ac14abc238448/Objects/dictobject.c#L3861-L3864
return super().__iter__()
def setdefault(self, key, default=None, /) -> t.Any:
if (value := self.get(key, _NoKeySentinel)) is not _NoKeySentinel:
return value
super().__setitem__(key, default)
return default
def items(self):
for key, value in super().items():
yield key, self._proxy_or_render_lazy_value(key, value)
def values(self):
for _key, value in self.items():
yield value
def pop(self, key, default=_NoKeySentinel, /) -> t.Any:
if (value := super().get(key, _NoKeySentinel)) is _NoKeySentinel:
if default is _NoKeySentinel:
raise KeyError(key)
return default
value = self._proxy_or_render_lazy_value(_NoKeySentinel, value)
del self[key]
return value
def popitem(self) -> t.Any:
try:
key = next(reversed(self))
except StopIteration:
raise KeyError("popitem(): dictionary is empty")
value = self._proxy_or_render_lazy_value(_NoKeySentinel, self[key])
del self[key]
return key, value
def _native_copy(self) -> dict:
return dict(self.items())
@staticmethod
def _item_source(value: dict) -> dict | _LazyValueSource:
if isinstance(value, _AnsibleLazyTemplateDict):
return _LazyValueSource(source=dict.items(value), templar=value._templar, lazy_options=value._lazy_options)
return value
def _yield_non_lazy_dict_items(self) -> t.Iterator[tuple[str, t.Any]]:
"""
Delegate to the base collection items iterator to yield the raw contents.
As of Python 3.13, generator functions are significantly faster than inline generator expressions.
"""
for k, v in dict.items(self):
yield k, v.value if type(v) is _LazyValue else v # pylint: disable=unidiomatic-typecheck
def _non_lazy_copy(self) -> dict:
return AnsibleTagHelper.tag_copy(self, self._yield_non_lazy_dict_items(), value_type=dict)
@staticmethod
def _lazy_values(values: dict, lazy_options: LazyOptions) -> _LazyValueSource:
return _LazyValueSource(source=((k, _LazyValue(v)) for k, v in values.items()), templar=TemplateContext.current().templar, lazy_options=lazy_options)
@staticmethod
def _proxy_or_render_other(other: t.Any | None) -> None:
"""Call `_proxy_or_render_lazy_values` if `other` is a lazy dict. Used internally by comparison methods."""
if type(other) is _AnsibleLazyTemplateDict: # pylint: disable=unidiomatic-typecheck
other._proxy_or_render_lazy_values()
def _proxy_or_render_lazy_values(self) -> None:
"""Ensure all `_LazyValue` wrapped values have been processed."""
for _unused in self.values():
pass
def __eq__(self, other):
self._proxy_or_render_lazy_values()
self._proxy_or_render_other(other)
return super().__eq__(other)
def __ne__(self, other):
self._proxy_or_render_lazy_values()
self._proxy_or_render_other(other)
return super().__ne__(other)
def __or__(self, other):
# DTFIX-RELEASE: support preservation of laziness when possible like we do for list
# Both sides end up going through _proxy_or_render_lazy_value, so there's no Templar preservation needed.
# In the future this could be made more lazy when both Templar instances are the same, or if per-value Templar tracking was used.
return super().__or__(other)
def __ror__(self, other):
# DTFIX-RELEASE: support preservation of laziness when possible like we do for list
# Both sides end up going through _proxy_or_render_lazy_value, so there's no Templar preservation needed.
# In the future this could be made more lazy when both Templar instances are the same, or if per-value Templar tracking was used.
return super().__ror__(other)
def __deepcopy__(self, memo):
return _AnsibleLazyTemplateDict(
_LazyValueSource(
source=((copy.deepcopy(k), copy.deepcopy(v)) for k, v in super().items()),
templar=copy.deepcopy(self._templar),
lazy_options=copy.deepcopy(self._lazy_options),
)
)
@t.final # consumers of lazy collections rely heavily on the concrete types being final
class _AnsibleLazyTemplateList(_AnsibleTaggedList, _AnsibleLazyTemplateMixin):
__slots__ = _AnsibleLazyTemplateMixin._SLOTS
def __init__(self, contents: t.Iterable | _LazyValueSource, /) -> None:
_AnsibleLazyTemplateMixin.__init__(self, contents)
if isinstance(contents, _AnsibleLazyTemplateList):
super().__init__(list.__iter__(contents))
elif isinstance(contents, _LazyValueSource):
super().__init__(contents.source)
else:
raise UnsupportedConstructionMethodError()
def __getitem__(self, key: t.SupportsIndex | slice, /) -> t.Any:
if type(key) is slice: # pylint: disable=unidiomatic-typecheck
return _AnsibleLazyTemplateList(_LazyValueSource(source=super().__getitem__(key), templar=self._templar, lazy_options=self._lazy_options))
return self._proxy_or_render_lazy_value(key, super().__getitem__(key))
def __iter__(self):
for key, value in enumerate(super().__iter__()):
yield self._proxy_or_render_lazy_value(key, value)
def pop(self, idx: t.SupportsIndex = -1, /) -> t.Any:
if not self:
raise IndexError('pop from empty list')
try:
value = self[idx]
except IndexError:
raise IndexError('pop index out of range')
value = self._proxy_or_render_lazy_value(_NoKeySentinel, value)
del self[idx]
return value
def __str__(self):
return str(self.copy()._native_copy()) # inefficient, but avoids mutating the current instance (to make debugging practical)
def __repr__(self):
return repr(self.copy()._native_copy()) # inefficient, but avoids mutating the current instance (to make debugging practical)
@staticmethod
def _item_source(value: list) -> list | _LazyValueSource:
if isinstance(value, _AnsibleLazyTemplateList):
return _LazyValueSource(source=list.__iter__(value), templar=value._templar, lazy_options=value._lazy_options)
return value
def _yield_non_lazy_list_items(self):
"""
Delegate to the base collection iterator to yield the raw contents.
As of Python 3.13, generator functions are significantly faster than inline generator expressions.
"""
for v in list.__iter__(self):
yield v.value if type(v) is _LazyValue else v # pylint: disable=unidiomatic-typecheck
def _non_lazy_copy(self) -> list:
return AnsibleTagHelper.tag_copy(self, self._yield_non_lazy_list_items(), value_type=list)
@staticmethod
def _lazy_values(values: list, lazy_options: LazyOptions) -> _LazyValueSource:
return _LazyValueSource(source=(_LazyValue(v) for v in values), templar=TemplateContext.current().templar, lazy_options=lazy_options)
@staticmethod
def _proxy_or_render_other(other: t.Any | None) -> None:
"""Call `_proxy_or_render_lazy_values` if `other` is a lazy list. Used internally by comparison methods."""
if type(other) is _AnsibleLazyTemplateList: # pylint: disable=unidiomatic-typecheck
other._proxy_or_render_lazy_values()
def _proxy_or_render_lazy_values(self) -> None:
"""Ensure all `_LazyValue` wrapped values have been processed."""
for _unused in self:
pass
def __eq__(self, other):
self._proxy_or_render_lazy_values()
self._proxy_or_render_other(other)
return super().__eq__(other)
def __ne__(self, other):
self._proxy_or_render_lazy_values()
self._proxy_or_render_other(other)
return super().__ne__(other)
def __gt__(self, other):
self._proxy_or_render_lazy_values()
self._proxy_or_render_other(other)
return super().__gt__(other)
def __ge__(self, other):
self._proxy_or_render_lazy_values()
self._proxy_or_render_other(other)
return super().__ge__(other)
def __lt__(self, other):
self._proxy_or_render_lazy_values()
self._proxy_or_render_other(other)
return super().__lt__(other)
def __le__(self, other):
self._proxy_or_render_lazy_values()
self._proxy_or_render_other(other)
return super().__le__(other)
def __contains__(self, item):
self._proxy_or_render_lazy_values()
return super().__contains__(item)
def __reversed__(self):
for idx in range(self.__len__() - 1, -1, -1):
yield self[idx]
def __add__(self, other):
if self._is_not_lazy_combine_candidate(other):
# When other is lazy with a different templar/options, it cannot be lazily combined with self and a plain list must be returned.
# If other is a list, de-lazify both, otherwise just let the operation fail.
if isinstance(other, _AnsibleLazyTemplateList):
self._proxy_or_render_lazy_values()
other._proxy_or_render_lazy_values()
return super().__add__(other)
# For all other cases, the new list inherits our templar and all values stay lazy.
# We use list.__add__ to avoid implementing all its error behavior.
return _AnsibleLazyTemplateList(_LazyValueSource(source=super().__add__(other), templar=self._templar, lazy_options=self._lazy_options))
def __radd__(self, other):
if not (other_add := getattr(other, '__add__', None)):
raise TypeError(f'unsupported operand type(s) for +: {type(other).__name__!r} and {type(self).__name__!r}') from None
return _AnsibleLazyTemplateList(_LazyValueSource(source=other_add(self), templar=self._templar, lazy_options=self._lazy_options))
def __mul__(self, other):
return _AnsibleLazyTemplateList(_LazyValueSource(source=super().__mul__(other), templar=self._templar, lazy_options=self._lazy_options))
def __rmul__(self, other):
return _AnsibleLazyTemplateList(_LazyValueSource(source=super().__rmul__(other), templar=self._templar, lazy_options=self._lazy_options))
def index(self, *args, **kwargs) -> int:
self._proxy_or_render_lazy_values()
return super().index(*args, **kwargs)
def remove(self, *args, **kwargs) -> None:
self._proxy_or_render_lazy_values()
super().remove(*args, **kwargs)
def sort(self, *args, **kwargs) -> None:
self._proxy_or_render_lazy_values()
super().sort(*args, **kwargs)
def __deepcopy__(self, memo):
return _AnsibleLazyTemplateList(
_LazyValueSource(
source=(copy.deepcopy(v) for v in super().__iter__()),
templar=copy.deepcopy(self._templar),
lazy_options=copy.deepcopy(self._lazy_options),
)
)
@t.final # consumers of lazy collections rely heavily on the concrete types being final
class _AnsibleLazyAccessTuple(_AnsibleTaggedTuple, _AnsibleLazyTemplateMixin):
"""
A tagged tuple subclass that provides only managed access for existing lazy values.
Since tuples are immutable, they cannot support lazy templating (which would change the tuple's value as templates were resolved).
When this type is created, each value in the source tuple is lazified:
* template strings are templated immediately (possibly resulting in lazy containers)
* non-tuple containers are lazy-wrapped
* tuples are immediately recursively lazy-wrapped
* transformations are applied immediately
The resulting object provides only managed access to its values (e.g., deprecation warnings, tripwires), and propagates to new lazy containers
created as a results of managed access.
"""
# DTFIX-RELEASE: ensure we have tests that explicitly verify this behavior
# nonempty __slots__ not supported for subtype of 'tuple'
def __new__(cls, contents: t.Iterable | _LazyValueSource, /) -> t.Self:
if isinstance(contents, _AnsibleLazyAccessTuple):
return super().__new__(cls, tuple.__iter__(contents))
if isinstance(contents, _LazyValueSource):
return super().__new__(cls, contents.source)
raise UnsupportedConstructionMethodError()
def __init__(self, contents: t.Iterable | _LazyValueSource, /) -> None:
_AnsibleLazyTemplateMixin.__init__(self, contents)
def __getitem__(self, key: t.SupportsIndex | slice, /) -> t.Any:
if type(key) is slice: # pylint: disable=unidiomatic-typecheck
return _AnsibleLazyAccessTuple(super().__getitem__(key))
value = super().__getitem__(key)
if self._lazy_options.access:
AnsibleAccessContext.current().access(value)
return value
@staticmethod
def _item_source(value: tuple) -> tuple | _LazyValueSource:
if isinstance(value, _AnsibleLazyAccessTuple):
return _LazyValueSource(source=tuple.__iter__(value), templar=value._templar, lazy_options=value._lazy_options)
return value
@staticmethod
def _lazy_values(values: t.Any, lazy_options: LazyOptions) -> _LazyValueSource:
templar = TemplateContext.current().templar
return _LazyValueSource(source=(templar.template(value, lazy_options=lazy_options) for value in values), templar=templar, lazy_options=lazy_options)
def _non_lazy_copy(self) -> tuple:
return AnsibleTagHelper.tag_copy(self, self, value_type=tuple)
def __deepcopy__(self, memo):
return _AnsibleLazyAccessTuple(
_LazyValueSource(
source=(copy.deepcopy(v) for v in super().__iter__()),
templar=copy.deepcopy(self._templar),
lazy_options=copy.deepcopy(self._lazy_options),
)
)
def lazify_container(value: t.Any) -> t.Any:
"""
If the given value is a supported container type, return its lazy version, otherwise return the value as-is.
This is used to ensure that managed access and templating occur on args and kwargs to a callable, even if they were sourced from Jinja constants.
Since both variable access and plugin output are already lazified, this mostly affects Jinja constant containers.
However, plugins that directly invoke other plugins (e.g., `Environment.call_filter`) are another potential source of non-lazy containers.
In these cases, templating will occur for trusted templates automatically upon access.
Sets, tuples, and dictionary keys cannot be lazy, since their correct operation requires hashability and equality.
These properties are mutually exclusive with the following lazy features:
- managed access on encrypted strings - may raise errors on both operations when decryption fails
- managed access on markers - must raise errors on both operations
- templating - mutates values
That leaves non-raising managed access as the only remaining feature, which is insufficient to warrant lazy support.
"""
return _AnsibleLazyTemplateMixin._try_create(value)
def lazify_container_args(item: tuple) -> tuple:
"""Return the given args with values converted to lazy containers as needed."""
return tuple(lazify_container(value) for value in item)
def lazify_container_kwargs(item: dict[str, t.Any]) -> dict[str, t.Any]:
"""Return the given kwargs with values converted to lazy containers as needed."""
return {key: lazify_container(value) for key, value in item.items()}
ansible_core-2.19.0b4/lib/ansible/_internal/_templating/_marker_behaviors.py 0000644 0000000 0000000 00000006557 15010426755 025733 0 ustar 00root root """Handling of `Marker` values."""
from __future__ import annotations
import abc
import contextlib
import dataclasses
import itertools
import typing as t
from ansible.utils.display import Display
from ._jinja_common import Marker
class MarkerBehavior(metaclass=abc.ABCMeta):
"""Base class to support custom handling of `Marker` values encountered during concatenation or finalization."""
@abc.abstractmethod
def handle_marker(self, value: Marker) -> t.Any:
"""Handle the given `Marker` value."""
class FailingMarkerBehavior(MarkerBehavior):
"""
The default behavior when encountering a `Marker` value during concatenation or finalization.
This always raises the template-internal `MarkerError` exception.
"""
def handle_marker(self, value: Marker) -> t.Any:
value.trip()
# FAIL_ON_MARKER_BEHAVIOR
# _DETONATE_MARKER_BEHAVIOR - internal singleton since it's the default and nobody should need to reference it, or make it an actual singleton
FAIL_ON_UNDEFINED: t.Final = FailingMarkerBehavior() # no sense in making many instances...
@dataclasses.dataclass(kw_only=True, slots=True, frozen=True)
class _MarkerTracker:
"""A numbered occurrence of a `Marker` value for later conversion to a warning."""
number: int
value: Marker
class ReplacingMarkerBehavior(MarkerBehavior):
"""All `Marker` values are replaced with a numbered string placeholder and the message from the value."""
def __init__(self) -> None:
self._trackers: list[_MarkerTracker] = []
def record_marker(self, value: Marker) -> t.Any:
"""Assign a sequence number to the given value and record it for later generation of warnings."""
number = len(self._trackers) + 1
self._trackers.append(_MarkerTracker(number=number, value=value))
return number
def emit_warnings(self) -> None:
"""Emit warning messages caused by Marker values, aggregated by unique template."""
display = Display()
grouped_templates = itertools.groupby(self._trackers, key=lambda tracker: tracker.value._marker_template_source)
for template, items in grouped_templates:
item_list = list(items)
msg = f'Encountered {len(item_list)} template error{"s" if len(item_list) > 1 else ""}.'
for item in item_list:
msg += f'\nerror {item.number} - {item.value._as_message()}'
display.warning(msg=msg, obj=template)
@classmethod
@contextlib.contextmanager
def warning_context(cls) -> t.Generator[t.Self, None, None]:
"""Collect warnings for `Marker` values and emit warnings when the context exits."""
instance = cls()
try:
yield instance
finally:
instance.emit_warnings()
def handle_marker(self, value: Marker) -> t.Any:
number = self.record_marker(value)
return f"<< error {number} - {value._as_message()} >>"
class RoutingMarkerBehavior(MarkerBehavior):
"""Routes instances of Marker (by type reference) to another MarkerBehavior, defaulting to FailingMarkerBehavior."""
def __init__(self, dispatch_table: dict[type[Marker], MarkerBehavior]) -> None:
self._dispatch_table = dispatch_table
def handle_marker(self, value: Marker) -> t.Any:
behavior = self._dispatch_table.get(type(value), FAIL_ON_UNDEFINED)
return behavior.handle_marker(value)
ansible_core-2.19.0b4/lib/ansible/_internal/_templating/_transform.py 0000644 0000000 0000000 00000004677 15010426755 024424 0 ustar 00root root """Runtime projections to provide template/var-visible views of objects that are not natively allowed in Ansible's type system."""
from __future__ import annotations
import dataclasses
import typing as t
from ansible.module_utils._internal import _traceback
from ansible.module_utils.common.messages import PluginInfo, ErrorSummary, WarningSummary, DeprecationSummary
from ansible.parsing.vault import EncryptedString, VaultHelper
from ansible.utils.display import Display
from ._jinja_common import VaultExceptionMarker
from .._errors import _captured, _utils
display = Display()
def plugin_info(value: PluginInfo) -> dict[str, str]:
"""Render PluginInfo as a dictionary."""
return dataclasses.asdict(value)
def error_summary(value: ErrorSummary) -> str:
"""Render ErrorSummary as a formatted traceback for backward-compatibility with pre-2.19 TaskResult.exception."""
return value.formatted_traceback or '(traceback unavailable)'
def warning_summary(value: WarningSummary) -> str:
"""Render WarningSummary as a simple message string for backward-compatibility with pre-2.19 TaskResult.warnings."""
return value._format()
def deprecation_summary(value: DeprecationSummary) -> dict[str, t.Any]:
"""Render DeprecationSummary as dict values for backward-compatibility with pre-2.19 TaskResult.deprecations."""
# DTFIX-RELEASE: reconsider which deprecation fields should be exposed here, taking into account that collection_name is to be deprecated
result = value._as_simple_dict()
result.pop('details')
return result
def encrypted_string(value: EncryptedString) -> str | VaultExceptionMarker:
"""Decrypt an encrypted string and return its value, or a VaultExceptionMarker if decryption fails."""
try:
return value._decrypt()
except Exception as ex:
return VaultExceptionMarker(
ciphertext=VaultHelper.get_ciphertext(value, with_tags=True),
reason=_utils.get_chained_message(ex),
traceback=_traceback.maybe_extract_traceback(ex, _traceback.TracebackEvent.ERROR),
)
_type_transform_mapping: dict[type, t.Callable[[t.Any], t.Any]] = {
_captured.CapturedErrorSummary: error_summary,
PluginInfo: plugin_info,
ErrorSummary: error_summary,
WarningSummary: warning_summary,
DeprecationSummary: deprecation_summary,
EncryptedString: encrypted_string,
}
"""This mapping is consulted by `Templar.template` to provide custom views of some objects."""
ansible_core-2.19.0b4/lib/ansible/_internal/_templating/_utils.py 0000644 0000000 0000000 00000007206 15010426755 023540 0 ustar 00root root from __future__ import annotations
import dataclasses
import typing as t
from ansible.module_utils._internal import _ambient_context, _datatag
if t.TYPE_CHECKING:
from ._engine import TemplateEngine, TemplateOptions
@dataclasses.dataclass(kw_only=True, slots=True, frozen=True)
class LazyOptions:
"""Templating options that apply to lazy containers, which are inherited by descendent lazy containers."""
DEFAULT: t.ClassVar[t.Self]
"""A shared instance with the default options to minimize instance creation for arg defaults."""
SKIP_TEMPLATES: t.ClassVar[t.Self]
"""A shared instance with only `template=False` set to minimize instance creation for arg defaults."""
SKIP_TEMPLATES_AND_ACCESS: t.ClassVar[t.Self]
"""A shared instance with both `template=False` and `access=False` set to minimize instance creation for arg defaults."""
template: bool = True
"""Enable/disable templating."""
access: bool = True
"""Enable/disables access calls."""
unmask_type_names: frozenset[str] = frozenset()
"""Disables template transformations for the provided type names."""
LazyOptions.DEFAULT = LazyOptions()
LazyOptions.SKIP_TEMPLATES = LazyOptions(template=False)
LazyOptions.SKIP_TEMPLATES_AND_ACCESS = LazyOptions(template=False, access=False)
class TemplateContext(_ambient_context.AmbientContextBase):
def __init__(
self,
*,
template_value: t.Any,
templar: TemplateEngine,
options: TemplateOptions,
stop_on_template: bool = False,
_render_jinja_const_template: bool = False,
):
self._template_value = template_value
self._templar = templar
self._options = options
self._stop_on_template = stop_on_template
self._parent_ctx = TemplateContext.current(optional=True)
self._render_jinja_const_template = _render_jinja_const_template
@property
def is_top_level(self) -> bool:
return not self._parent_ctx
@property
def template_value(self) -> t.Any:
return self._template_value
@property
def templar(self) -> TemplateEngine:
return self._templar
@property
def options(self) -> TemplateOptions:
return self._options
@property
def stop_on_template(self) -> bool:
return self._stop_on_template
class _OmitType:
"""
A placeholder singleton used to dynamically omit items from a dict/list/tuple/set when the value is `Omit`.
The `Omit` singleton is accessible from all Ansible templating contexts via the Jinja global name `omit`.
The `Omit` placeholder value will be visible to Jinja plugins during templating.
Jinja plugins requiring omit behavior are responsible for handling encountered `Omit` values.
`Omit` values remaining in template results will be automatically dropped during template finalization.
When a finalized template renders to a scalar `Omit`, `AnsibleValueOmittedError` will be raised.
Passing a value other than `Omit` for `value_for_omit` to the `template` call allows that value to be substituted instead of raising.
"""
__slots__ = ()
def __new__(cls):
return Omit
def __repr__(self):
return "<>"
Omit = object.__new__(_OmitType)
_datatag._untaggable_types.add(_OmitType)
# DTFIX-RELEASE: review these type sets to ensure they're not overly permissive/dynamic
IGNORE_SCALAR_VAR_TYPES = {value for value in _datatag._ANSIBLE_ALLOWED_SCALAR_VAR_TYPES if not issubclass(value, str)}
PASS_THROUGH_SCALAR_VAR_TYPES = _datatag._ANSIBLE_ALLOWED_SCALAR_VAR_TYPES | {
_OmitType, # allow pass through of omit for later handling after top-level finalize completes
}
ansible_core-2.19.0b4/lib/ansible/_internal/_testing.py 0000644 0000000 0000000 00000001471 15010426755 021550 0 ustar 00root root """
Testing utilities for use in integration tests, not unit tests or non-test code.
Provides better error behavior than Python's `assert` statement.
"""
from __future__ import annotations
import contextlib
import typing as t
class _Checker:
@staticmethod
def check(value: object, msg: str | None = 'Value is not truthy.') -> None:
"""Raise an `AssertionError` if the given `value` is not truthy."""
if not value:
raise AssertionError(msg)
@contextlib.contextmanager
def hard_fail_context(msg: str) -> t.Generator[_Checker]:
"""Enter a context which converts all exceptions to `BaseException` and provides a `Checker` instance for making assertions."""
try:
yield _Checker()
except BaseException as ex:
raise BaseException(f"Hard failure: {msg}") from ex
ansible_core-2.19.0b4/lib/ansible/_internal/_wrapt.py 0000644 0000000 0000000 00000112113 15010426755 021224 0 ustar 00root root # Copyright (c) 2013-2023, Graham Dumpleton
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# * Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
# copied from https://github.com/GrahamDumpleton/wrapt/blob/1.15.0/src/wrapt/wrappers.py
# LOCAL PATCHES:
# - disabled optional relative import of the _wrappers C extension; we shouldn't need it
from __future__ import annotations
# The following makes it easier for us to script updates of the bundled code
_BUNDLED_METADATA = {"pypi_name": "wrapt", "version": "1.15.0"}
import os
import sys
import functools
import operator
import weakref
import inspect
PY2 = sys.version_info[0] == 2
if PY2:
string_types = basestring,
else:
string_types = str,
def with_metaclass(meta, *bases):
"""Create a base class with a metaclass."""
return meta("NewBase", bases, {})
class _ObjectProxyMethods(object):
# We use properties to override the values of __module__ and
# __doc__. If we add these in ObjectProxy, the derived class
# __dict__ will still be setup to have string variants of these
# attributes and the rules of descriptors means that they appear to
# take precedence over the properties in the base class. To avoid
# that, we copy the properties into the derived class type itself
# via a meta class. In that way the properties will always take
# precedence.
@property
def __module__(self):
return self.__wrapped__.__module__
@__module__.setter
def __module__(self, value):
self.__wrapped__.__module__ = value
@property
def __doc__(self):
return self.__wrapped__.__doc__
@__doc__.setter
def __doc__(self, value):
self.__wrapped__.__doc__ = value
# We similar use a property for __dict__. We need __dict__ to be
# explicit to ensure that vars() works as expected.
@property
def __dict__(self):
return self.__wrapped__.__dict__
# Need to also propagate the special __weakref__ attribute for case
# where decorating classes which will define this. If do not define
# it and use a function like inspect.getmembers() on a decorator
# class it will fail. This can't be in the derived classes.
@property
def __weakref__(self):
return self.__wrapped__.__weakref__
class _ObjectProxyMetaType(type):
def __new__(cls, name, bases, dictionary):
# Copy our special properties into the class so that they
# always take precedence over attributes of the same name added
# during construction of a derived class. This is to save
# duplicating the implementation for them in all derived classes.
dictionary.update(vars(_ObjectProxyMethods))
return type.__new__(cls, name, bases, dictionary)
class ObjectProxy(with_metaclass(_ObjectProxyMetaType)):
__slots__ = '__wrapped__'
def __init__(self, wrapped):
object.__setattr__(self, '__wrapped__', wrapped)
# Python 3.2+ has the __qualname__ attribute, but it does not
# allow it to be overridden using a property and it must instead
# be an actual string object instead.
try:
object.__setattr__(self, '__qualname__', wrapped.__qualname__)
except AttributeError:
pass
# Python 3.10 onwards also does not allow itself to be overridden
# using a property and it must instead be set explicitly.
try:
object.__setattr__(self, '__annotations__', wrapped.__annotations__)
except AttributeError:
pass
@property
def __name__(self):
return self.__wrapped__.__name__
@__name__.setter
def __name__(self, value):
self.__wrapped__.__name__ = value
@property
def __class__(self):
return self.__wrapped__.__class__
@__class__.setter
def __class__(self, value):
self.__wrapped__.__class__ = value
def __dir__(self):
return dir(self.__wrapped__)
def __str__(self):
return str(self.__wrapped__)
if not PY2:
def __bytes__(self):
return bytes(self.__wrapped__)
def __repr__(self):
return '<{} at 0x{:x} for {} at 0x{:x}>'.format(
type(self).__name__, id(self),
type(self.__wrapped__).__name__,
id(self.__wrapped__))
def __reversed__(self):
return reversed(self.__wrapped__)
if not PY2:
def __round__(self):
return round(self.__wrapped__)
if sys.hexversion >= 0x03070000:
def __mro_entries__(self, bases):
return (self.__wrapped__,)
def __lt__(self, other):
return self.__wrapped__ < other
def __le__(self, other):
return self.__wrapped__ <= other
def __eq__(self, other):
return self.__wrapped__ == other
def __ne__(self, other):
return self.__wrapped__ != other
def __gt__(self, other):
return self.__wrapped__ > other
def __ge__(self, other):
return self.__wrapped__ >= other
def __hash__(self):
return hash(self.__wrapped__)
def __nonzero__(self):
return bool(self.__wrapped__)
def __bool__(self):
return bool(self.__wrapped__)
def __setattr__(self, name, value):
if name.startswith('_self_'):
object.__setattr__(self, name, value)
elif name == '__wrapped__':
object.__setattr__(self, name, value)
try:
object.__delattr__(self, '__qualname__')
except AttributeError:
pass
try:
object.__setattr__(self, '__qualname__', value.__qualname__)
except AttributeError:
pass
try:
object.__delattr__(self, '__annotations__')
except AttributeError:
pass
try:
object.__setattr__(self, '__annotations__', value.__annotations__)
except AttributeError:
pass
elif name == '__qualname__':
setattr(self.__wrapped__, name, value)
object.__setattr__(self, name, value)
elif name == '__annotations__':
setattr(self.__wrapped__, name, value)
object.__setattr__(self, name, value)
elif hasattr(type(self), name):
object.__setattr__(self, name, value)
else:
setattr(self.__wrapped__, name, value)
def __getattr__(self, name):
# If we are being to lookup '__wrapped__' then the
# '__init__()' method cannot have been called.
if name == '__wrapped__':
raise ValueError('wrapper has not been initialised')
return getattr(self.__wrapped__, name)
def __delattr__(self, name):
if name.startswith('_self_'):
object.__delattr__(self, name)
elif name == '__wrapped__':
raise TypeError('__wrapped__ must be an object')
elif name == '__qualname__':
object.__delattr__(self, name)
delattr(self.__wrapped__, name)
elif hasattr(type(self), name):
object.__delattr__(self, name)
else:
delattr(self.__wrapped__, name)
def __add__(self, other):
return self.__wrapped__ + other
def __sub__(self, other):
return self.__wrapped__ - other
def __mul__(self, other):
return self.__wrapped__ * other
def __div__(self, other):
return operator.div(self.__wrapped__, other)
def __truediv__(self, other):
return operator.truediv(self.__wrapped__, other)
def __floordiv__(self, other):
return self.__wrapped__ // other
def __mod__(self, other):
return self.__wrapped__ % other
def __divmod__(self, other):
return divmod(self.__wrapped__, other)
def __pow__(self, other, *args):
return pow(self.__wrapped__, other, *args)
def __lshift__(self, other):
return self.__wrapped__ << other
def __rshift__(self, other):
return self.__wrapped__ >> other
def __and__(self, other):
return self.__wrapped__ & other
def __xor__(self, other):
return self.__wrapped__ ^ other
def __or__(self, other):
return self.__wrapped__ | other
def __radd__(self, other):
return other + self.__wrapped__
def __rsub__(self, other):
return other - self.__wrapped__
def __rmul__(self, other):
return other * self.__wrapped__
def __rdiv__(self, other):
return operator.div(other, self.__wrapped__)
def __rtruediv__(self, other):
return operator.truediv(other, self.__wrapped__)
def __rfloordiv__(self, other):
return other // self.__wrapped__
def __rmod__(self, other):
return other % self.__wrapped__
def __rdivmod__(self, other):
return divmod(other, self.__wrapped__)
def __rpow__(self, other, *args):
return pow(other, self.__wrapped__, *args)
def __rlshift__(self, other):
return other << self.__wrapped__
def __rrshift__(self, other):
return other >> self.__wrapped__
def __rand__(self, other):
return other & self.__wrapped__
def __rxor__(self, other):
return other ^ self.__wrapped__
def __ror__(self, other):
return other | self.__wrapped__
def __iadd__(self, other):
self.__wrapped__ += other
return self
def __isub__(self, other):
self.__wrapped__ -= other
return self
def __imul__(self, other):
self.__wrapped__ *= other
return self
def __idiv__(self, other):
self.__wrapped__ = operator.idiv(self.__wrapped__, other)
return self
def __itruediv__(self, other):
self.__wrapped__ = operator.itruediv(self.__wrapped__, other)
return self
def __ifloordiv__(self, other):
self.__wrapped__ //= other
return self
def __imod__(self, other):
self.__wrapped__ %= other
return self
def __ipow__(self, other):
self.__wrapped__ **= other
return self
def __ilshift__(self, other):
self.__wrapped__ <<= other
return self
def __irshift__(self, other):
self.__wrapped__ >>= other
return self
def __iand__(self, other):
self.__wrapped__ &= other
return self
def __ixor__(self, other):
self.__wrapped__ ^= other
return self
def __ior__(self, other):
self.__wrapped__ |= other
return self
def __neg__(self):
return -self.__wrapped__
def __pos__(self):
return +self.__wrapped__
def __abs__(self):
return abs(self.__wrapped__)
def __invert__(self):
return ~self.__wrapped__
def __int__(self):
return int(self.__wrapped__)
def __long__(self):
return long(self.__wrapped__)
def __float__(self):
return float(self.__wrapped__)
def __complex__(self):
return complex(self.__wrapped__)
def __oct__(self):
return oct(self.__wrapped__)
def __hex__(self):
return hex(self.__wrapped__)
def __index__(self):
return operator.index(self.__wrapped__)
def __len__(self):
return len(self.__wrapped__)
def __contains__(self, value):
return value in self.__wrapped__
def __getitem__(self, key):
return self.__wrapped__[key]
def __setitem__(self, key, value):
self.__wrapped__[key] = value
def __delitem__(self, key):
del self.__wrapped__[key]
def __getslice__(self, i, j):
return self.__wrapped__[i:j]
def __setslice__(self, i, j, value):
self.__wrapped__[i:j] = value
def __delslice__(self, i, j):
del self.__wrapped__[i:j]
def __enter__(self):
return self.__wrapped__.__enter__()
def __exit__(self, *args, **kwargs):
return self.__wrapped__.__exit__(*args, **kwargs)
def __iter__(self):
return iter(self.__wrapped__)
def __copy__(self):
raise NotImplementedError('object proxy must define __copy__()')
def __deepcopy__(self, memo):
raise NotImplementedError('object proxy must define __deepcopy__()')
def __reduce__(self):
raise NotImplementedError(
'object proxy must define __reduce_ex__()')
def __reduce_ex__(self, protocol):
raise NotImplementedError(
'object proxy must define __reduce_ex__()')
class CallableObjectProxy(ObjectProxy):
def __call__(*args, **kwargs):
def _unpack_self(self, *args):
return self, args
self, args = _unpack_self(*args)
return self.__wrapped__(*args, **kwargs)
class PartialCallableObjectProxy(ObjectProxy):
def __init__(*args, **kwargs):
def _unpack_self(self, *args):
return self, args
self, args = _unpack_self(*args)
if len(args) < 1:
raise TypeError('partial type takes at least one argument')
wrapped, args = args[0], args[1:]
if not callable(wrapped):
raise TypeError('the first argument must be callable')
super(PartialCallableObjectProxy, self).__init__(wrapped)
self._self_args = args
self._self_kwargs = kwargs
def __call__(*args, **kwargs):
def _unpack_self(self, *args):
return self, args
self, args = _unpack_self(*args)
_args = self._self_args + args
_kwargs = dict(self._self_kwargs)
_kwargs.update(kwargs)
return self.__wrapped__(*_args, **_kwargs)
class _FunctionWrapperBase(ObjectProxy):
__slots__ = ('_self_instance', '_self_wrapper', '_self_enabled',
'_self_binding', '_self_parent')
def __init__(self, wrapped, instance, wrapper, enabled=None,
binding='function', parent=None):
super(_FunctionWrapperBase, self).__init__(wrapped)
object.__setattr__(self, '_self_instance', instance)
object.__setattr__(self, '_self_wrapper', wrapper)
object.__setattr__(self, '_self_enabled', enabled)
object.__setattr__(self, '_self_binding', binding)
object.__setattr__(self, '_self_parent', parent)
def __get__(self, instance, owner):
# This method is actually doing double duty for both unbound and
# bound derived wrapper classes. It should possibly be broken up
# and the distinct functionality moved into the derived classes.
# Can't do that straight away due to some legacy code which is
# relying on it being here in this base class.
#
# The distinguishing attribute which determines whether we are
# being called in an unbound or bound wrapper is the parent
# attribute. If binding has never occurred, then the parent will
# be None.
#
# First therefore, is if we are called in an unbound wrapper. In
# this case we perform the binding.
#
# We have one special case to worry about here. This is where we
# are decorating a nested class. In this case the wrapped class
# would not have a __get__() method to call. In that case we
# simply return self.
#
# Note that we otherwise still do binding even if instance is
# None and accessing an unbound instance method from a class.
# This is because we need to be able to later detect that
# specific case as we will need to extract the instance from the
# first argument of those passed in.
if self._self_parent is None:
if not inspect.isclass(self.__wrapped__):
descriptor = self.__wrapped__.__get__(instance, owner)
return self.__bound_function_wrapper__(descriptor, instance,
self._self_wrapper, self._self_enabled,
self._self_binding, self)
return self
# Now we have the case of binding occurring a second time on what
# was already a bound function. In this case we would usually
# return ourselves again. This mirrors what Python does.
#
# The special case this time is where we were originally bound
# with an instance of None and we were likely an instance
# method. In that case we rebind against the original wrapped
# function from the parent again.
if self._self_instance is None and self._self_binding == 'function':
descriptor = self._self_parent.__wrapped__.__get__(
instance, owner)
return self._self_parent.__bound_function_wrapper__(
descriptor, instance, self._self_wrapper,
self._self_enabled, self._self_binding,
self._self_parent)
return self
def __call__(*args, **kwargs):
def _unpack_self(self, *args):
return self, args
self, args = _unpack_self(*args)
# If enabled has been specified, then evaluate it at this point
# and if the wrapper is not to be executed, then simply return
# the bound function rather than a bound wrapper for the bound
# function. When evaluating enabled, if it is callable we call
# it, otherwise we evaluate it as a boolean.
if self._self_enabled is not None:
if callable(self._self_enabled):
if not self._self_enabled():
return self.__wrapped__(*args, **kwargs)
elif not self._self_enabled:
return self.__wrapped__(*args, **kwargs)
# This can occur where initial function wrapper was applied to
# a function that was already bound to an instance. In that case
# we want to extract the instance from the function and use it.
if self._self_binding in ('function', 'classmethod'):
if self._self_instance is None:
instance = getattr(self.__wrapped__, '__self__', None)
if instance is not None:
return self._self_wrapper(self.__wrapped__, instance,
args, kwargs)
# This is generally invoked when the wrapped function is being
# called as a normal function and is not bound to a class as an
# instance method. This is also invoked in the case where the
# wrapped function was a method, but this wrapper was in turn
# wrapped using the staticmethod decorator.
return self._self_wrapper(self.__wrapped__, self._self_instance,
args, kwargs)
def __set_name__(self, owner, name):
# This is a special method use to supply information to
# descriptors about what the name of variable in a class
# definition is. Not wanting to add this to ObjectProxy as not
# sure of broader implications of doing that. Thus restrict to
# FunctionWrapper used by decorators.
if hasattr(self.__wrapped__, "__set_name__"):
self.__wrapped__.__set_name__(owner, name)
def __instancecheck__(self, instance):
# This is a special method used by isinstance() to make checks
# instance of the `__wrapped__`.
return isinstance(instance, self.__wrapped__)
def __subclasscheck__(self, subclass):
# This is a special method used by issubclass() to make checks
# about inheritance of classes. We need to upwrap any object
# proxy. Not wanting to add this to ObjectProxy as not sure of
# broader implications of doing that. Thus restrict to
# FunctionWrapper used by decorators.
if hasattr(subclass, "__wrapped__"):
return issubclass(subclass.__wrapped__, self.__wrapped__)
else:
return issubclass(subclass, self.__wrapped__)
class BoundFunctionWrapper(_FunctionWrapperBase):
def __call__(*args, **kwargs):
def _unpack_self(self, *args):
return self, args
self, args = _unpack_self(*args)
# If enabled has been specified, then evaluate it at this point
# and if the wrapper is not to be executed, then simply return
# the bound function rather than a bound wrapper for the bound
# function. When evaluating enabled, if it is callable we call
# it, otherwise we evaluate it as a boolean.
if self._self_enabled is not None:
if callable(self._self_enabled):
if not self._self_enabled():
return self.__wrapped__(*args, **kwargs)
elif not self._self_enabled:
return self.__wrapped__(*args, **kwargs)
# We need to do things different depending on whether we are
# likely wrapping an instance method vs a static method or class
# method.
if self._self_binding == 'function':
if self._self_instance is None:
# This situation can occur where someone is calling the
# instancemethod via the class type and passing the instance
# as the first argument. We need to shift the args before
# making the call to the wrapper and effectively bind the
# instance to the wrapped function using a partial so the
# wrapper doesn't see anything as being different.
if not args:
raise TypeError('missing 1 required positional argument')
instance, args = args[0], args[1:]
wrapped = PartialCallableObjectProxy(self.__wrapped__, instance)
return self._self_wrapper(wrapped, instance, args, kwargs)
return self._self_wrapper(self.__wrapped__, self._self_instance,
args, kwargs)
else:
# As in this case we would be dealing with a classmethod or
# staticmethod, then _self_instance will only tell us whether
# when calling the classmethod or staticmethod they did it via an
# instance of the class it is bound to and not the case where
# done by the class type itself. We thus ignore _self_instance
# and use the __self__ attribute of the bound function instead.
# For a classmethod, this means instance will be the class type
# and for a staticmethod it will be None. This is probably the
# more useful thing we can pass through even though we loose
# knowledge of whether they were called on the instance vs the
# class type, as it reflects what they have available in the
# decoratored function.
instance = getattr(self.__wrapped__, '__self__', None)
return self._self_wrapper(self.__wrapped__, instance, args,
kwargs)
class FunctionWrapper(_FunctionWrapperBase):
__bound_function_wrapper__ = BoundFunctionWrapper
def __init__(self, wrapped, wrapper, enabled=None):
# What it is we are wrapping here could be anything. We need to
# try and detect specific cases though. In particular, we need
# to detect when we are given something that is a method of a
# class. Further, we need to know when it is likely an instance
# method, as opposed to a class or static method. This can
# become problematic though as there isn't strictly a fool proof
# method of knowing.
#
# The situations we could encounter when wrapping a method are:
#
# 1. The wrapper is being applied as part of a decorator which
# is a part of the class definition. In this case what we are
# given is the raw unbound function, classmethod or staticmethod
# wrapper objects.
#
# The problem here is that we will not know we are being applied
# in the context of the class being set up. This becomes
# important later for the case of an instance method, because in
# that case we just see it as a raw function and can't
# distinguish it from wrapping a normal function outside of
# a class context.
#
# 2. The wrapper is being applied when performing monkey
# patching of the class type afterwards and the method to be
# wrapped was retrieved direct from the __dict__ of the class
# type. This is effectively the same as (1) above.
#
# 3. The wrapper is being applied when performing monkey
# patching of the class type afterwards and the method to be
# wrapped was retrieved from the class type. In this case
# binding will have been performed where the instance against
# which the method is bound will be None at that point.
#
# This case is a problem because we can no longer tell if the
# method was a static method, plus if using Python3, we cannot
# tell if it was an instance method as the concept of an
# unnbound method no longer exists.
#
# 4. The wrapper is being applied when performing monkey
# patching of an instance of a class. In this case binding will
# have been perfomed where the instance was not None.
#
# This case is a problem because we can no longer tell if the
# method was a static method.
#
# Overall, the best we can do is look at the original type of the
# object which was wrapped prior to any binding being done and
# see if it is an instance of classmethod or staticmethod. In
# the case where other decorators are between us and them, if
# they do not propagate the __class__ attribute so that the
# isinstance() checks works, then likely this will do the wrong
# thing where classmethod and staticmethod are used.
#
# Since it is likely to be very rare that anyone even puts
# decorators around classmethod and staticmethod, likelihood of
# that being an issue is very small, so we accept it and suggest
# that those other decorators be fixed. It is also only an issue
# if a decorator wants to actually do things with the arguments.
#
# As to not being able to identify static methods properly, we
# just hope that that isn't something people are going to want
# to wrap, or if they do suggest they do it the correct way by
# ensuring that it is decorated in the class definition itself,
# or patch it in the __dict__ of the class type.
#
# So to get the best outcome we can, whenever we aren't sure what
# it is, we label it as a 'function'. If it was already bound and
# that is rebound later, we assume that it will be an instance
# method and try an cope with the possibility that the 'self'
# argument it being passed as an explicit argument and shuffle
# the arguments around to extract 'self' for use as the instance.
if isinstance(wrapped, classmethod):
binding = 'classmethod'
elif isinstance(wrapped, staticmethod):
binding = 'staticmethod'
elif hasattr(wrapped, '__self__'):
if inspect.isclass(wrapped.__self__):
binding = 'classmethod'
else:
binding = 'function'
else:
binding = 'function'
super(FunctionWrapper, self).__init__(wrapped, None, wrapper,
enabled, binding)
# disabled support for native extension; we likely don't need it
# try:
# if not os.environ.get('WRAPT_DISABLE_EXTENSIONS'):
# from ._wrappers import (ObjectProxy, CallableObjectProxy,
# PartialCallableObjectProxy, FunctionWrapper,
# BoundFunctionWrapper, _FunctionWrapperBase)
# except ImportError:
# pass
# Helper functions for applying wrappers to existing functions.
def resolve_path(module, name):
if isinstance(module, string_types):
__import__(module)
module = sys.modules[module]
parent = module
path = name.split('.')
attribute = path[0]
# We can't just always use getattr() because in doing
# that on a class it will cause binding to occur which
# will complicate things later and cause some things not
# to work. For the case of a class we therefore access
# the __dict__ directly. To cope though with the wrong
# class being given to us, or a method being moved into
# a base class, we need to walk the class hierarchy to
# work out exactly which __dict__ the method was defined
# in, as accessing it from __dict__ will fail if it was
# not actually on the class given. Fallback to using
# getattr() if we can't find it. If it truly doesn't
# exist, then that will fail.
def lookup_attribute(parent, attribute):
if inspect.isclass(parent):
for cls in inspect.getmro(parent):
if attribute in vars(cls):
return vars(cls)[attribute]
else:
return getattr(parent, attribute)
else:
return getattr(parent, attribute)
original = lookup_attribute(parent, attribute)
for attribute in path[1:]:
parent = original
original = lookup_attribute(parent, attribute)
return (parent, attribute, original)
def apply_patch(parent, attribute, replacement):
setattr(parent, attribute, replacement)
def wrap_object(module, name, factory, args=(), kwargs={}):
(parent, attribute, original) = resolve_path(module, name)
wrapper = factory(original, *args, **kwargs)
apply_patch(parent, attribute, wrapper)
return wrapper
# Function for applying a proxy object to an attribute of a class
# instance. The wrapper works by defining an attribute of the same name
# on the class which is a descriptor and which intercepts access to the
# instance attribute. Note that this cannot be used on attributes which
# are themselves defined by a property object.
class AttributeWrapper(object):
def __init__(self, attribute, factory, args, kwargs):
self.attribute = attribute
self.factory = factory
self.args = args
self.kwargs = kwargs
def __get__(self, instance, owner):
value = instance.__dict__[self.attribute]
return self.factory(value, *self.args, **self.kwargs)
def __set__(self, instance, value):
instance.__dict__[self.attribute] = value
def __delete__(self, instance):
del instance.__dict__[self.attribute]
def wrap_object_attribute(module, name, factory, args=(), kwargs={}):
path, attribute = name.rsplit('.', 1)
parent = resolve_path(module, path)[2]
wrapper = AttributeWrapper(attribute, factory, args, kwargs)
apply_patch(parent, attribute, wrapper)
return wrapper
# Functions for creating a simple decorator using a FunctionWrapper,
# plus short cut functions for applying wrappers to functions. These are
# for use when doing monkey patching. For a more featured way of
# creating decorators see the decorator decorator instead.
def function_wrapper(wrapper):
def _wrapper(wrapped, instance, args, kwargs):
target_wrapped = args[0]
if instance is None:
target_wrapper = wrapper
elif inspect.isclass(instance):
target_wrapper = wrapper.__get__(None, instance)
else:
target_wrapper = wrapper.__get__(instance, type(instance))
return FunctionWrapper(target_wrapped, target_wrapper)
return FunctionWrapper(wrapper, _wrapper)
def wrap_function_wrapper(module, name, wrapper):
return wrap_object(module, name, FunctionWrapper, (wrapper,))
def patch_function_wrapper(module, name):
def _wrapper(wrapper):
return wrap_object(module, name, FunctionWrapper, (wrapper,))
return _wrapper
def transient_function_wrapper(module, name):
def _decorator(wrapper):
def _wrapper(wrapped, instance, args, kwargs):
target_wrapped = args[0]
if instance is None:
target_wrapper = wrapper
elif inspect.isclass(instance):
target_wrapper = wrapper.__get__(None, instance)
else:
target_wrapper = wrapper.__get__(instance, type(instance))
def _execute(wrapped, instance, args, kwargs):
(parent, attribute, original) = resolve_path(module, name)
replacement = FunctionWrapper(original, target_wrapper)
setattr(parent, attribute, replacement)
try:
return wrapped(*args, **kwargs)
finally:
setattr(parent, attribute, original)
return FunctionWrapper(target_wrapped, _execute)
return FunctionWrapper(wrapper, _wrapper)
return _decorator
# A weak function proxy. This will work on instance methods, class
# methods, static methods and regular functions. Special treatment is
# needed for the method types because the bound method is effectively a
# transient object and applying a weak reference to one will immediately
# result in it being destroyed and the weakref callback called. The weak
# reference is therefore applied to the instance the method is bound to
# and the original function. The function is then rebound at the point
# of a call via the weak function proxy.
def _weak_function_proxy_callback(ref, proxy, callback):
if proxy._self_expired:
return
proxy._self_expired = True
# This could raise an exception. We let it propagate back and let
# the weakref.proxy() deal with it, at which point it generally
# prints out a short error message direct to stderr and keeps going.
if callback is not None:
callback(proxy)
class WeakFunctionProxy(ObjectProxy):
__slots__ = ('_self_expired', '_self_instance')
def __init__(self, wrapped, callback=None):
# We need to determine if the wrapped function is actually a
# bound method. In the case of a bound method, we need to keep a
# reference to the original unbound function and the instance.
# This is necessary because if we hold a reference to the bound
# function, it will be the only reference and given it is a
# temporary object, it will almost immediately expire and
# the weakref callback triggered. So what is done is that we
# hold a reference to the instance and unbound function and
# when called bind the function to the instance once again and
# then call it. Note that we avoid using a nested function for
# the callback here so as not to cause any odd reference cycles.
_callback = callback and functools.partial(
_weak_function_proxy_callback, proxy=self,
callback=callback)
self._self_expired = False
if isinstance(wrapped, _FunctionWrapperBase):
self._self_instance = weakref.ref(wrapped._self_instance,
_callback)
if wrapped._self_parent is not None:
super(WeakFunctionProxy, self).__init__(
weakref.proxy(wrapped._self_parent, _callback))
else:
super(WeakFunctionProxy, self).__init__(
weakref.proxy(wrapped, _callback))
return
try:
self._self_instance = weakref.ref(wrapped.__self__, _callback)
super(WeakFunctionProxy, self).__init__(
weakref.proxy(wrapped.__func__, _callback))
except AttributeError:
self._self_instance = None
super(WeakFunctionProxy, self).__init__(
weakref.proxy(wrapped, _callback))
def __call__(*args, **kwargs):
def _unpack_self(self, *args):
return self, args
self, args = _unpack_self(*args)
# We perform a boolean check here on the instance and wrapped
# function as that will trigger the reference error prior to
# calling if the reference had expired.
instance = self._self_instance and self._self_instance()
function = self.__wrapped__ and self.__wrapped__
# If the wrapped function was originally a bound function, for
# which we retained a reference to the instance and the unbound
# function we need to rebind the function and then call it. If
# not just called the wrapped function.
if instance is None:
return self.__wrapped__(*args, **kwargs)
return function.__get__(instance, type(instance))(*args, **kwargs) ansible_core-2.19.0b4/lib/ansible/_internal/_yaml/ 0000755 0000000 0000000 00000000000 15010426755 020460 5 ustar 00root root ansible_core-2.19.0b4/lib/ansible/_internal/_yaml/__init__.py 0000644 0000000 0000000 00000000000 15010426755 022557 0 ustar 00root root ansible_core-2.19.0b4/lib/ansible/_internal/_yaml/_constructor.py 0000644 0000000 0000000 00000023046 15010426755 023563 0 ustar 00root root from __future__ import annotations
import abc
import copy
import typing as t
from yaml import Node
from yaml.constructor import SafeConstructor
from yaml.resolver import BaseResolver
from ansible import constants as C
from ansible.module_utils.common.text.converters import to_text
from ansible.module_utils._internal._datatag import AnsibleTagHelper
from ansible._internal._datatag._tags import Origin, TrustedAsTemplate
from ansible.parsing.vault import EncryptedString
from ansible.utils.display import Display
from ._errors import AnsibleConstructorError
display = Display()
_TRUSTED_AS_TEMPLATE: t.Final[TrustedAsTemplate] = TrustedAsTemplate()
class _BaseConstructor(SafeConstructor, metaclass=abc.ABCMeta):
"""Base class for Ansible YAML constructors."""
@classmethod
@abc.abstractmethod
def _register_constructors(cls) -> None:
"""Method used to register constructors to derived types during class initialization."""
def __init_subclass__(cls, **kwargs) -> None:
"""Initialization for derived types."""
cls._register_constructors()
class AnsibleInstrumentedConstructor(_BaseConstructor):
"""Ansible constructor which supports Ansible custom behavior such as `Origin` tagging, but no Ansible-specific YAML tags."""
name: t.Any # provided by the YAML parser, which retrieves it from the stream
def __init__(self, origin: Origin, trusted_as_template: bool) -> None:
if not origin.line_num:
origin = origin.replace(line_num=1)
self._origin = origin
self._trusted_as_template = trusted_as_template
self._duplicate_key_mode = C.config.get_config_value('DUPLICATE_YAML_DICT_KEY')
super().__init__()
@property
def trusted_as_template(self) -> bool:
return self._trusted_as_template
def construct_yaml_map(self, node):
data = self._node_position_info(node).tag({}) # always an ordered dictionary on py3.7+
yield data
value = self.construct_mapping(node)
data.update(value)
def construct_mapping(self, node, deep=False):
# Delegate to built-in implementation to construct the mapping.
# This is done before checking for duplicates to leverage existing error checking on the input node.
mapping = super().construct_mapping(node, deep)
keys = set()
# Now that the node is known to be a valid mapping, handle any duplicate keys.
for key_node, _value_node in node.value:
if (key := self.construct_object(key_node, deep=deep)) in keys:
msg = f'Found duplicate mapping key {key!r}.'
if self._duplicate_key_mode == 'error':
raise AnsibleConstructorError(problem=msg, problem_mark=key_node.start_mark)
if self._duplicate_key_mode == 'warn':
display.warning(msg=msg, obj=key, help_text='Using last defined value only.')
keys.add(key)
return mapping
def construct_yaml_int(self, node):
value = super().construct_yaml_int(node)
return self._node_position_info(node).tag(value)
def construct_yaml_float(self, node):
value = super().construct_yaml_float(node)
return self._node_position_info(node).tag(value)
def construct_yaml_timestamp(self, node):
value = super().construct_yaml_timestamp(node)
return self._node_position_info(node).tag(value)
def construct_yaml_omap(self, node):
origin = self._node_position_info(node)
display.deprecated(
msg='Use of the YAML `!!omap` tag is deprecated.',
version='2.23',
obj=origin,
help_text='Use a standard mapping instead, as key order is always preserved.',
)
items = list(super().construct_yaml_omap(node))[0]
items = [origin.tag(item) for item in items]
yield origin.tag(items)
def construct_yaml_pairs(self, node):
origin = self._node_position_info(node)
display.deprecated(
msg='Use of the YAML `!!pairs` tag is deprecated.',
version='2.23',
obj=origin,
help_text='Use a standard mapping instead.',
)
items = list(super().construct_yaml_pairs(node))[0]
items = [origin.tag(item) for item in items]
yield origin.tag(items)
def construct_yaml_str(self, node):
# Override the default string handling function
# to always return unicode objects
# DTFIX-FUTURE: is this to_text conversion still necessary under Py3?
value = to_text(self.construct_scalar(node))
tags = [self._node_position_info(node)]
if self.trusted_as_template:
# NB: since we're not context aware, this will happily add trust to dictionary keys; this is actually necessary for
# certain backward compat scenarios, though might be accomplished in other ways if we wanted to avoid trusting keys in
# the general scenario
tags.append(_TRUSTED_AS_TEMPLATE)
return AnsibleTagHelper.tag(value, tags)
def construct_yaml_binary(self, node):
value = super().construct_yaml_binary(node)
return AnsibleTagHelper.tag(value, self._node_position_info(node))
def construct_yaml_set(self, node):
data = AnsibleTagHelper.tag(set(), self._node_position_info(node))
yield data
value = self.construct_mapping(node)
data.update(value)
def construct_yaml_seq(self, node):
data = self._node_position_info(node).tag([])
yield data
data.extend(self.construct_sequence(node))
def _resolve_and_construct_object(self, node):
# use a copied node to avoid mutating existing node and tripping the recursion check in construct_object
copied_node = copy.copy(node)
# repeat implicit resolution process to determine the proper tag for the value in the unsafe node
copied_node.tag = t.cast(BaseResolver, self).resolve(type(node), node.value, (True, False))
# re-entrant call using the correct tag
# non-deferred construction of hierarchical nodes so the result is a fully realized object, and so our stateful unsafe propagation behavior works
return self.construct_object(copied_node, deep=True)
def _node_position_info(self, node) -> Origin:
# the line number where the previous token has ended (plus empty lines)
# Add one so that the first line is line 1 rather than line 0
return self._origin.replace(line_num=node.start_mark.line + self._origin.line_num, col_num=node.start_mark.column + 1)
@classmethod
def _register_constructors(cls) -> None:
constructors: dict[str, t.Callable] = {
'tag:yaml.org,2002:binary': cls.construct_yaml_binary,
'tag:yaml.org,2002:float': cls.construct_yaml_float,
'tag:yaml.org,2002:int': cls.construct_yaml_int,
'tag:yaml.org,2002:map': cls.construct_yaml_map,
'tag:yaml.org,2002:omap': cls.construct_yaml_omap,
'tag:yaml.org,2002:pairs': cls.construct_yaml_pairs,
'tag:yaml.org,2002:python/dict': cls.construct_yaml_map,
'tag:yaml.org,2002:python/unicode': cls.construct_yaml_str,
'tag:yaml.org,2002:seq': cls.construct_yaml_seq,
'tag:yaml.org,2002:set': cls.construct_yaml_set,
'tag:yaml.org,2002:str': cls.construct_yaml_str,
'tag:yaml.org,2002:timestamp': cls.construct_yaml_timestamp,
}
for tag, constructor in constructors.items():
cls.add_constructor(tag, constructor)
class AnsibleConstructor(AnsibleInstrumentedConstructor):
"""Ansible constructor which supports Ansible custom behavior such as `Origin` tagging, as well as Ansible-specific YAML tags."""
def __init__(self, origin: Origin, trusted_as_template: bool) -> None:
self._unsafe_depth = 0 # volatile state var used during recursive construction of a value tagged unsafe
super().__init__(origin=origin, trusted_as_template=trusted_as_template)
@property
def trusted_as_template(self) -> bool:
return self._trusted_as_template and not self._unsafe_depth
def construct_yaml_unsafe(self, node):
self._unsafe_depth += 1
try:
return self._resolve_and_construct_object(node)
finally:
self._unsafe_depth -= 1
def construct_yaml_vault(self, node: Node) -> EncryptedString:
ciphertext = self._resolve_and_construct_object(node)
if not isinstance(ciphertext, str):
raise AnsibleConstructorError(problem=f"the {node.tag!r} tag requires a string value", problem_mark=node.start_mark)
encrypted_string = AnsibleTagHelper.tag_copy(ciphertext, EncryptedString(ciphertext=AnsibleTagHelper.untag(ciphertext)))
return encrypted_string
def construct_yaml_vault_encrypted(self, node: Node) -> EncryptedString:
origin = self._node_position_info(node)
display.deprecated(
msg='Use of the YAML `!vault-encrypted` tag is deprecated.',
version='2.23',
obj=origin,
help_text='Use the `!vault` tag instead.',
)
return self.construct_yaml_vault(node)
@classmethod
def _register_constructors(cls) -> None:
super()._register_constructors()
constructors: dict[str, t.Callable] = {
'!unsafe': cls.construct_yaml_unsafe,
'!vault': cls.construct_yaml_vault,
'!vault-encrypted': cls.construct_yaml_vault_encrypted,
}
for tag, constructor in constructors.items():
cls.add_constructor(tag, constructor)
ansible_core-2.19.0b4/lib/ansible/_internal/_yaml/_dumper.py 0000644 0000000 0000000 00000004726 15010426755 022476 0 ustar 00root root from __future__ import annotations
import abc
import collections.abc as c
import typing as t
from yaml.representer import SafeRepresenter
from ansible.module_utils._internal._datatag import AnsibleTaggedObject, Tripwire, AnsibleTagHelper
from ansible.parsing.vault import VaultHelper
from ansible.module_utils.common.yaml import HAS_LIBYAML
if HAS_LIBYAML:
from yaml.cyaml import CSafeDumper as SafeDumper
else:
from yaml import SafeDumper # type: ignore[assignment]
class _BaseDumper(SafeDumper, metaclass=abc.ABCMeta):
"""Base class for Ansible YAML dumpers."""
@classmethod
@abc.abstractmethod
def _register_representers(cls) -> None:
"""Method used to register representers to derived types during class initialization."""
def __init_subclass__(cls, **kwargs) -> None:
"""Initialization for derived types."""
cls._register_representers()
class AnsibleDumper(_BaseDumper):
"""A simple stub class that allows us to add representers for our custom types."""
# DTFIX-RELEASE: need a better way to handle serialization controls during YAML dumping
def __init__(self, *args, dump_vault_tags: bool | None = None, **kwargs):
super().__init__(*args, **kwargs)
self._dump_vault_tags = dump_vault_tags
@classmethod
def _register_representers(cls) -> None:
cls.add_multi_representer(AnsibleTaggedObject, cls.represent_ansible_tagged_object)
cls.add_multi_representer(Tripwire, cls.represent_tripwire)
cls.add_multi_representer(c.Mapping, SafeRepresenter.represent_dict)
cls.add_multi_representer(c.Sequence, SafeRepresenter.represent_list)
def represent_ansible_tagged_object(self, data):
if self._dump_vault_tags is not False and (ciphertext := VaultHelper.get_ciphertext(data, with_tags=False)):
# deprecated: description='enable the deprecation warning below' core_version='2.23'
# if self._dump_vault_tags is None:
# Display().deprecated(
# msg="Implicit YAML dumping of vaulted value ciphertext is deprecated. Set `dump_vault_tags` to explicitly specify the desired behavior",
# version="2.27",
# )
return self.represent_scalar('!vault', ciphertext, style='|')
return self.represent_data(AnsibleTagHelper.as_native_type(data)) # automatically decrypts encrypted strings
def represent_tripwire(self, data: Tripwire) -> t.NoReturn:
data.trip()
ansible_core-2.19.0b4/lib/ansible/_internal/_yaml/_errors.py 0000644 0000000 0000000 00000017113 15010426755 022510 0 ustar 00root root from __future__ import annotations
import re
import typing as t
from yaml import MarkedYAMLError
from yaml.constructor import ConstructorError
from ansible._internal._errors import _utils
from ansible.errors import AnsibleParserError
from ansible._internal._datatag._tags import Origin
class AnsibleConstructorError(ConstructorError):
"""Ansible-specific ConstructorError used to bypass exception analysis during wrapping in AnsibleYAMLParserError."""
class AnsibleYAMLParserError(AnsibleParserError):
"""YAML-specific parsing failure wrapping an exception raised by the YAML parser."""
_default_message = 'YAML parsing failed.'
_include_cause_message = False # hide the underlying cause message, it's included by `handle_exception` as needed
_formatted_source_context_value: str | None = None
@property
def _formatted_source_context(self) -> str | None:
return self._formatted_source_context_value
@classmethod
def handle_exception(cls, exception: Exception, origin: Origin) -> t.NoReturn:
if isinstance(exception, MarkedYAMLError):
origin = origin.replace(line_num=exception.problem_mark.line + 1, col_num=exception.problem_mark.column + 1)
source_context = _utils.SourceContext.from_origin(origin)
target_line = source_context.target_line or '' # for these cases, we don't need to distinguish between None and empty string
message: str | None = None
help_text = None
# FIXME: Do all this by walking the parsed YAML doc stream. Using regexes is a dead-end; YAML's just too flexible to not have a
# raft of false-positives and corner cases. If we directly consume either the YAML parse stream or override the YAML composer, we can
# better catch these things without worrying about duplicating YAML's scalar parsing logic around quoting/escaping. At first, we can
# replace the regex logic below with tiny special-purpose parse consumers to catch specific issues, but ideally, we could do a lot of this
# inline with the actual doc parse, since our rules are a lot more strict than YAML's (eg, no support for non-scalar keys), and a lot of the
# problem cases where that comes into play are around expression quoting and Jinja {{ syntax looking like weird YAML values we don't support.
# Some common examples, where -> is "what YAML actually sees":
# foo: {{ bar }} -> {"foo": {{"bar": None}: None}} - a mapping with a mapping as its key (legal YAML, but not legal Python/Ansible)
#
# - copy: src=foo.txt # kv syntax (kv could be on following line(s), too- implicit multi-line block scalar)
# dest: bar.txt # orphaned mapping, since the value of `copy` is the scalar "src=foo.txt"
#
# - msg == "Error: 'dude' was not found" # unquoted scalar has a : in it -> {'msg == "Error"': 'dude'} [ was not found" ] is garbage orphan scalar
# noinspection PyUnboundLocalVariable
if not isinstance(exception, MarkedYAMLError):
pass # unexpected exception, don't use special analysis of exception
elif isinstance(exception, AnsibleConstructorError):
pass # raised internally by ansible code, don't use special analysis of exception
# Check for tabs.
# There may be cases where there is a valid tab in a line that has other errors.
# That's OK, users should "fix" their tab usage anyway -- at which point later error handling logic will hopefully find the real issue.
elif (tab_idx := target_line.find('\t')) >= 0:
source_context = _utils.SourceContext.from_origin(origin.replace(col_num=tab_idx + 1))
message = "Tabs are usually invalid in YAML."
# Check for unquoted templates.
elif match := re.search(r'^\s*(?:-\s+)*(?:[\w\s]+:\s+)?(?P\{\{.*}})', target_line):
source_context = _utils.SourceContext.from_origin(origin.replace(col_num=match.start('value') + 1))
message = 'This may be an issue with missing quotes around a template block.'
# FIXME: Use the captured value to show the actual fix required.
help_text = """
For example:
raw: {{ some_var }}
Should be:
raw: "{{ some_var }}"
"""
# Check for common unquoted colon mistakes.
elif (
# ignore lines starting with only whitespace and a colon
not target_line.lstrip().startswith(':')
# find the value after list/dict preamble
and (value_match := re.search(r'^\s*(?:-\s+)*(?:[\w\s\[\]{}]+:\s+)?(?P.*)$', target_line))
# ignore properly quoted values
and (target_fragment := _replace_quoted_value(value_match.group('value')))
# look for an unquoted colon in the value
and (colon_match := re.search(r':($| )', target_fragment))
):
source_context = _utils.SourceContext.from_origin(origin.replace(col_num=value_match.start('value') + colon_match.start() + 1))
message = 'Colons in unquoted values must be followed by a non-space character.'
# FIXME: Use the captured value to show the actual fix required.
help_text = """
For example:
raw: echo 'name: ansible'
Should be:
raw: "echo 'name: ansible'"
"""
# Check for common quoting mistakes.
elif match := re.search(r'^\s*(?:-\s+)*(?:[\w\s]+:\s+)?(?P[\"\'].*?\s*)$', target_line):
suspected_value = match.group('value')
first, last = suspected_value[0], suspected_value[-1]
if first != last: # "foo" in bar
source_context = _utils.SourceContext.from_origin(origin.replace(col_num=match.start('value') + 1))
message = 'Values starting with a quote must end with the same quote.'
# FIXME: Use the captured value to show the actual fix required, and use that same logic to improve the origin further.
help_text = """
For example:
raw: "foo" in bar
Should be:
raw: '"foo" in bar'
"""
elif first == last and target_line.count(first) > 2: # "foo" and "bar"
source_context = _utils.SourceContext.from_origin(origin.replace(col_num=match.start('value') + 1))
message = 'Values starting with a quote must end with the same quote, and not contain that quote.'
# FIXME: Use the captured value to show the actual fix required, and use that same logic to improve the origin further.
help_text = """
For example:
raw: "foo" in "bar"
Should be:
raw: '"foo" in "bar"'
"""
if not message:
if isinstance(exception, MarkedYAMLError):
# marked YAML error, pull out the useful messages while omitting the noise
message = ' '.join(filter(None, (exception.context, exception.problem, exception.note)))
message = message.strip()
message = f'{message[0].upper()}{message[1:]}'
if not message.endswith('.'):
message += '.'
else:
# unexpected error, use the exception message (normally hidden by overriding include_cause_message)
message = str(exception)
message = re.sub(r'\s+', ' ', message).strip()
error = cls(message, obj=source_context.origin)
error._formatted_source_context_value = str(source_context)
error._help_text = help_text
raise error from exception
def _replace_quoted_value(value: str, replacement='.') -> str:
return re.sub(r"""^\s*('[^']*'|"[^"]*")\s*$""", lambda match: replacement * len(match.group(0)), value)
ansible_core-2.19.0b4/lib/ansible/_internal/_yaml/_loader.py 0000644 0000000 0000000 00000004604 15010426755 022443 0 ustar 00root root from __future__ import annotations
import io as _io
from yaml.resolver import Resolver
from ansible.module_utils._internal._datatag import AnsibleTagHelper
from ansible.module_utils.common.yaml import HAS_LIBYAML
from ansible._internal._datatag import _tags
from ._constructor import AnsibleConstructor, AnsibleInstrumentedConstructor
if HAS_LIBYAML:
from yaml.cyaml import CParser
class _YamlParser(CParser):
def __init__(self, stream: str | bytes | _io.IOBase) -> None:
if isinstance(stream, (str, bytes)):
stream = AnsibleTagHelper.untag(stream) # PyYAML + libyaml barfs on str/bytes subclasses
CParser.__init__(self, stream)
self.name = getattr(stream, 'name', None) # provide feature parity with the Python implementation (yaml.reader.Reader provides name)
else:
from yaml.composer import Composer
from yaml.reader import Reader
from yaml.scanner import Scanner
from yaml.parser import Parser
class _YamlParser(Reader, Scanner, Parser, Composer): # type: ignore[no-redef]
def __init__(self, stream: str | bytes | _io.IOBase) -> None:
Reader.__init__(self, stream)
Scanner.__init__(self)
Parser.__init__(self)
Composer.__init__(self)
class AnsibleInstrumentedLoader(_YamlParser, AnsibleInstrumentedConstructor, Resolver):
"""Ansible YAML loader which supports Ansible custom behavior such as `Origin` tagging, but no Ansible-specific YAML tags."""
def __init__(self, stream: str | bytes | _io.IOBase) -> None:
_YamlParser.__init__(self, stream)
AnsibleInstrumentedConstructor.__init__(
self,
origin=_tags.Origin.get_or_create_tag(stream, self.name),
trusted_as_template=_tags.TrustedAsTemplate.is_tagged_on(stream),
)
Resolver.__init__(self)
class AnsibleLoader(_YamlParser, AnsibleConstructor, Resolver):
"""Ansible loader which supports Ansible custom behavior such as `Origin` tagging, as well as Ansible-specific YAML tags."""
def __init__(self, stream: str | bytes | _io.IOBase) -> None:
_YamlParser.__init__(self, stream)
AnsibleConstructor.__init__(
self,
origin=_tags.Origin.get_or_create_tag(stream, self.name),
trusted_as_template=_tags.TrustedAsTemplate.is_tagged_on(stream),
)
Resolver.__init__(self)
ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ 0000755 0000000 0000000 00000000000 15010426755 023372 5 ustar 00root root ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/ 0000755 0000000 0000000 00000000000 15010426755 025007 5 ustar 00root root ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/ 0000755 0000000 0000000 00000000000 15010426755 027526 5 ustar 00root root ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/README.md 0000644 0000000 0000000 00000001144 15010426755 031005 0 ustar 00root root "Protomatter - an unstable substance which every ethical scientist in the galaxy has denounced as dangerously unpredictable."
"But it was the only way to solve certain problems..."
This Ansible Collection is embedded within ansible-core.
It contains plugins useful for ansible-core's own integration tests.
They have been made available, completely unsupported,
in case they prove useful for debugging and troubleshooting purposes.
> CAUTION: This collection is not supported, and may be changed or removed in any version without prior notice.
Use of these plugins outside ansible-core is highly discouraged.
ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/ 0000755 0000000 0000000 00000000000 15010426755 031207 5 ustar 00root root ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/action/0000755 0000000 0000000 00000000000 15010426755 032464 5 ustar 00root root ././@PaxHeader 0000000 0000000 0000000 00000000166 00000000000 010220 x ustar 00 118 path=ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/action/debug.py
ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/action/0000644 0000000 0000000 00000002675 15010426755 032500 0 ustar 00root root from __future__ import annotations
import typing as t
from ansible.module_utils.common.validation import _check_type_str_no_conversion, _check_type_list_strict
from ansible.plugins.action import ActionBase
from ansible._internal._templating._engine import TemplateEngine
from ansible._internal._templating._marker_behaviors import ReplacingMarkerBehavior
class ActionModule(ActionBase):
TRANSFERS_FILES = False
_requires_connection = False
@classmethod
def finalize_task_arg(cls, name: str, value: t.Any, templar: TemplateEngine, context: t.Any) -> t.Any:
if name == 'expression':
return value
return super().finalize_task_arg(name, value, templar, context)
def run(self, tmp=None, task_vars=None):
# accepts a list of literal expressions (no templating), evaluates with no failure on undefined, returns all results
_vr, args = self.validate_argument_spec(
argument_spec=dict(
expression=dict(type=_check_type_list_strict, elements=_check_type_str_no_conversion, required=True),
),
)
with ReplacingMarkerBehavior.warning_context() as replacing_behavior:
templar = self._templar._engine.extend(marker_behavior=replacing_behavior)
return dict(
_ansible_verbose_always=True,
expression_result=[templar.evaluate_expression(expression) for expression in args['expression']],
)
ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/0000755 0000000 0000000 00000000000 15010426755 032474 5 ustar 00root root ././@PaxHeader 0000000 0000000 0000000 00000000174 00000000000 010217 x ustar 00 124 path=ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/apply_trust.py
ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/0000644 0000000 0000000 00000001031 15010426755 032471 0 ustar 00root root from __future__ import annotations
import typing as t
from ansible._internal._datatag._tags import TrustedAsTemplate
def apply_trust(value: object) -> object:
"""
Filter that returns a tagged copy of the input string with TrustedAsTemplate.
Containers and other non-string values are returned unmodified.
"""
return TrustedAsTemplate().tag(value) if isinstance(value, str) else value
class FilterModule:
@staticmethod
def filters() -> dict[str, t.Callable]:
return dict(apply_trust=apply_trust)
././@PaxHeader 0000000 0000000 0000000 00000000174 00000000000 010217 x ustar 00 124 path=ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/dump_object.py
ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/0000644 0000000 0000000 00000000722 15010426755 032477 0 ustar 00root root from __future__ import annotations
import dataclasses
import typing as t
def dump_object(value: t.Any) -> object:
"""Internal filter to convert objects not supported by JSON to types which are."""
if dataclasses.is_dataclass(value):
return dataclasses.asdict(value) # type: ignore[arg-type]
return value
class FilterModule(object):
@staticmethod
def filters() -> dict[str, t.Callable]:
return dict(dump_object=dump_object)
././@PaxHeader 0000000 0000000 0000000 00000000171 00000000000 010214 x ustar 00 121 path=ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/finalize.py
ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/0000644 0000000 0000000 00000000730 15010426755 032476 0 ustar 00root root from __future__ import annotations
import typing as t
from ansible._internal._templating._engine import _finalize_template_result, FinalizeMode
def finalize(value: t.Any) -> t.Any:
"""Perform an explicit top-level template finalize operation on the supplied value."""
return _finalize_template_result(value, mode=FinalizeMode.TOP_LEVEL)
class FilterModule:
@staticmethod
def filters() -> dict[str, t.Callable]:
return dict(finalize=finalize)
././@PaxHeader 0000000 0000000 0000000 00000000167 00000000000 010221 x ustar 00 119 path=ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/origin.py
ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/0000644 0000000 0000000 00000000655 15010426755 032504 0 ustar 00root root from __future__ import annotations
import typing as t
from ansible._internal._datatag._tags import Origin
def origin(value: object) -> str | None:
"""Return the origin of the value, if any, otherwise `None`."""
origin_tag = Origin.get_tag(value)
return str(origin_tag) if origin_tag else None
class FilterModule:
@staticmethod
def filters() -> dict[str, t.Callable]:
return dict(origin=origin)
././@PaxHeader 0000000 0000000 0000000 00000000204 00000000000 010211 x ustar 00 132 path=ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.py
ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/0000644 0000000 0000000 00000001050 15010426755 032472 0 ustar 00root root from __future__ import annotations
import ast
from ansible.errors import AnsibleTypeError
def python_literal_eval(value: object, ignore_errors=False) -> object:
try:
if isinstance(value, str):
return ast.literal_eval(value)
raise AnsibleTypeError("The `value` to eval must be a string.", obj=value)
except Exception:
if ignore_errors:
return value
raise
class FilterModule(object):
@staticmethod
def filters():
return dict(python_literal_eval=python_literal_eval)
././@PaxHeader 0000000 0000000 0000000 00000000205 00000000000 010212 x ustar 00 133 path=ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/python_literal_eval.yml
ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/0000644 0000000 0000000 00000002645 15010426755 032505 0 ustar 00root root DOCUMENTATION:
name: python_literal_eval
version_added: "2.19"
short_description: evaluate a Python literal expression string
description:
- Evaluates the input string as a Python literal expression, returning the resulting data structure.
- Previous versions of Ansible applied this behavior to all template results in non-native Jinja mode.
- This filter provides a way to emulate the previous behavior.
notes:
- Directly calls Python's C(ast.literal_eval).
positional: _input
options:
_input:
description: Python literal string expression.
type: str
required: true
ignore_errors:
description: Whether to silently ignore all errors resulting from the literal_eval operation. If true, the input is silently returned unmodified when an error occurs.
type: bool
default: false
EXAMPLES: |
- name: evaluate an expression comprised only of Python literals
assert:
that: (another_var | ansible._protomatter.python_literal_eval)[1] == 2 # in 2.19 and later, the explicit python_literal_eval emulates the old templating behavior
vars:
another_var: "{{ some_var }}" # in 2.18 and earlier, indirection through templating caused implicit literal_eval, converting the value to a list
some_var: "[1, 2]" # a value that looks like a Python list literal embedded in a string
RETURN:
_value:
description: Resulting data structure.
type: raw
././@PaxHeader 0000000 0000000 0000000 00000000172 00000000000 010215 x ustar 00 122 path=ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/tag_names.py
ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/0000644 0000000 0000000 00000000716 15010426755 032502 0 ustar 00root root from __future__ import annotations
import typing as t
from ansible.module_utils._internal._datatag import AnsibleTagHelper
def tag_names(value: object) -> list[str]:
"""Return a list of tag type names (if any) present on the given object."""
return sorted(tag_type.__name__ for tag_type in AnsibleTagHelper.tag_types(value))
class FilterModule:
@staticmethod
def filters() -> dict[str, t.Callable]:
return dict(tag_names=tag_names)
././@PaxHeader 0000000 0000000 0000000 00000000172 00000000000 010215 x ustar 00 122 path=ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/true_type.py
ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/0000644 0000000 0000000 00000000710 15010426755 032474 0 ustar 00root root from __future__ import annotations
import typing as t
from ansible.plugins import accept_args_markers
@accept_args_markers
def true_type(obj: object) -> str:
"""Internal filter to show the true type name of the given object, not just the base type name like the `debug` filter."""
return obj.__class__.__name__
class FilterModule(object):
@staticmethod
def filters() -> dict[str, t.Callable]:
return dict(true_type=true_type)
././@PaxHeader 0000000 0000000 0000000 00000000167 00000000000 010221 x ustar 00 119 path=ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/unmask.py
ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/filter/0000644 0000000 0000000 00000003334 15010426755 032501 0 ustar 00root root from __future__ import annotations
import copy
import dataclasses
import typing as t
from ansible._internal._templating._jinja_common import validate_arg_type
from ansible._internal._templating._lazy_containers import _AnsibleLazyTemplateMixin
from ansible._internal._templating._transform import _type_transform_mapping
from ansible.errors import AnsibleError
def unmask(value: object, type_names: str | list[str]) -> object:
"""
Internal filter to suppress automatic type transformation in Jinja (e.g., WarningMessageDetail, DeprecationMessageDetail, ErrorDetail).
Lazy collection caching is in play - the first attempt to access a value in a given lazy container must be with unmasking in place, or the transformed value
will already be cached.
"""
validate_arg_type("type_names", type_names, (str, list))
if isinstance(type_names, str):
check_type_names = [type_names]
else:
check_type_names = type_names
valid_type_names = {key.__name__ for key in _type_transform_mapping}
invalid_type_names = [type_name for type_name in check_type_names if type_name not in valid_type_names]
if invalid_type_names:
raise AnsibleError(f'Unknown type name(s): {", ".join(invalid_type_names)}', obj=type_names)
result: object
if isinstance(value, _AnsibleLazyTemplateMixin):
result = copy.copy(value)
result._lazy_options = dataclasses.replace(
result._lazy_options,
unmask_type_names=result._lazy_options.unmask_type_names | frozenset(check_type_names),
)
else:
result = value
return result
class FilterModule(object):
@staticmethod
def filters() -> dict[str, t.Callable]:
return dict(unmask=unmask)
ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/0000755 0000000 0000000 00000000000 15010426755 032520 5 ustar 00root root ././@PaxHeader 0000000 0000000 0000000 00000000167 00000000000 010221 x ustar 00 119 path=ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.py
ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/0000644 0000000 0000000 00000001462 15010426755 032525 0 ustar 00root root from __future__ import annotations
from ansible.plugins.lookup import LookupBase
class LookupModule(LookupBase):
"""Specialized config lookup that applies data transformations on values that config cannot."""
def run(self, terms, variables=None, **kwargs):
if not terms or not (config_name := terms[0]):
raise ValueError("config name is required")
match config_name:
case 'DISPLAY_TRACEBACK':
# since config can't expand this yet, we need the post-processed version
from ansible.module_utils._internal._traceback import traceback_for
return traceback_for()
# DTFIX-FUTURE: plumb through normal config fallback
case _:
raise ValueError(f"Unknown config name {config_name!r}.")
././@PaxHeader 0000000 0000000 0000000 00000000170 00000000000 010213 x ustar 00 120 path=ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/config.yml
ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/lookup/0000644 0000000 0000000 00000000036 15010426755 032521 0 ustar 00root root DOCUMENTATION:
name: config
ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/ 0000755 0000000 0000000 00000000000 15010426755 032166 5 ustar 00root root ././@PaxHeader 0000000 0000000 0000000 00000000165 00000000000 010217 x ustar 00 117 path=ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.py
ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/ta0000644 0000000 0000000 00000000477 15010426755 032525 0 ustar 00root root from __future__ import annotations
import typing as t
from ansible.module_utils._internal import _datatag
def tagged(value: t.Any) -> bool:
return bool(_datatag.AnsibleTagHelper.tag_types(value))
class TestModule:
@staticmethod
def tests() -> dict[str, t.Callable]:
return dict(tagged=tagged)
././@PaxHeader 0000000 0000000 0000000 00000000166 00000000000 010220 x ustar 00 118 path=ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged.yml
ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/ta0000644 0000000 0000000 00000000733 15010426755 032520 0 ustar 00root root DOCUMENTATION:
name: tagged
author: Ansible Core
version_added: "2.19"
short_description: does the value have a data tag
description:
- Check if the provided value has a data tag.
options:
_input:
description: A value.
type: raw
EXAMPLES: |
is_data_tagged: "{{ my_variable is ansible._protomatter.tagged }}"
RETURN:
_value:
description: Returns C(True) if the value has one or more data tags, otherwise C(False).
type: boolean
././@PaxHeader 0000000 0000000 0000000 00000000172 00000000000 010215 x ustar 00 122 path=ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.py
ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/ta0000644 0000000 0000000 00000000705 15010426755 032517 0 ustar 00root root from __future__ import annotations
import typing as t
from ansible.module_utils._internal import _datatag
def tagged_with(value: t.Any, tag_name: str) -> bool:
if tag_type := _datatag._known_tag_type_map.get(tag_name):
return tag_type.is_tagged_on(value)
raise ValueError(f"Unknown tag name {tag_name!r}.")
class TestModule:
@staticmethod
def tests() -> dict[str, t.Callable]:
return dict(tagged_with=tagged_with)
././@PaxHeader 0000000 0000000 0000000 00000000173 00000000000 010216 x ustar 00 123 path=ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/tagged_with.yml
ansible_core-2.19.0b4/lib/ansible/_internal/ansible_collections/ansible/_protomatter/plugins/test/ta0000644 0000000 0000000 00000001010 15010426755 032505 0 ustar 00root root DOCUMENTATION:
name: tagged_with
author: Ansible Core
version_added: "2.19"
short_description: does the value have the specified data tag
description:
- Check if the provided value has the specified data tag.
options:
_input:
description: A value.
type: raw
EXAMPLES: |
is_data_tagged: "{{ my_variable is ansible._protomatter.tagged_with('Origin') }}"
RETURN:
_value:
description: Returns C(True) if the value has the specified data tag, otherwise C(False).
type: boolean
ansible_core-2.19.0b4/lib/ansible/_vendor/ 0000755 0000000 0000000 00000000000 15010426755 017040 5 ustar 00root root ansible_core-2.19.0b4/lib/ansible/_vendor/__init__.py 0000644 0000000 0000000 00000003761 15010426755 021160 0 ustar 00root root # (c) 2020 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import annotations
import os
import pkgutil
import sys
import warnings
# This package exists to host vendored top-level Python packages for downstream packaging. Any Python packages
# installed beneath this one will be masked from the Ansible loader, and available from the front of sys.path.
# It is expected that the vendored packages will be loaded very early, so a warning will be fired on import of
# the top-level ansible package if any packages beneath this are already loaded at that point.
#
# Python packages may be installed here during downstream packaging using something like:
# pip install --upgrade -t (path to this dir) cryptography pyyaml packaging jinja2
# mask vendored content below this package from being accessed as an ansible subpackage
__path__ = []
def _ensure_vendored_path_entry():
"""
Ensure that any downstream-bundled content beneath this package is available at the top of sys.path
"""
# patch our vendored dir onto sys.path
vendored_path_entry = os.path.dirname(__file__)
vendored_module_names = set(m[1] for m in pkgutil.iter_modules([vendored_path_entry], '')) # m[1] == m.name
if vendored_module_names:
# patch us early to load vendored deps transparently
if vendored_path_entry in sys.path:
# handle reload case by removing the existing entry, wherever it might be
sys.path.remove(vendored_path_entry)
sys.path.insert(0, vendored_path_entry)
already_loaded_vendored_modules = set(sys.modules.keys()).intersection(vendored_module_names)
if already_loaded_vendored_modules:
warnings.warn('One or more Python packages bundled by this ansible-core distribution were already '
'loaded ({0}). This may result in undefined behavior.'.format(', '.join(sorted(already_loaded_vendored_modules))))
_ensure_vendored_path_entry()
ansible_core-2.19.0b4/lib/ansible/cli/ 0000755 0000000 0000000 00000000000 15010426755 016153 5 ustar 00root root ansible_core-2.19.0b4/lib/ansible/cli/__init__.py 0000644 0000000 0000000 00000074015 15010426755 020273 0 ustar 00root root # Copyright: (c) 2012-2014, Michael DeHaan
# Copyright: (c) 2016, Toshio Kuratomi
# Copyright: (c) 2018, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import annotations
import locale
import os
import signal
import sys
# We overload the ``ansible`` adhoc command to provide the functionality for
# ``SSH_ASKPASS``. This code is here, and not in ``adhoc.py`` to bypass
# unnecessary code. The program provided to ``SSH_ASKPASS`` can only be invoked
# as a singular command, ``python -m`` doesn't work for that use case, and we
# aren't adding a new entrypoint at this time. Assume that if we are executing
# and there is only a single item in argv plus the executable, and the env var
# is set we are in ``SSH_ASKPASS`` mode
if 1 <= len(sys.argv) <= 2 and os.path.basename(sys.argv[0]) == "ansible" and os.getenv('_ANSIBLE_SSH_ASKPASS_SHM'):
from ansible.cli import _ssh_askpass
_ssh_askpass.main()
# Used for determining if the system is running a new enough python version
# and should only restrict on our documented minimum versions
if sys.version_info < (3, 11):
raise SystemExit(
'ERROR: Ansible requires Python 3.11 or newer on the controller. '
'Current version: %s' % ''.join(sys.version.splitlines())
)
def check_blocking_io():
"""Check stdin/stdout/stderr to make sure they are using blocking IO."""
handles = []
for handle in (sys.stdin, sys.stdout, sys.stderr):
# noinspection PyBroadException
try:
fd = handle.fileno()
except Exception:
continue # not a real file handle, such as during the import sanity test
if not os.get_blocking(fd):
handles.append(getattr(handle, 'name', None) or '#%s' % fd)
if handles:
raise SystemExit('ERROR: Ansible requires blocking IO on stdin/stdout/stderr. '
'Non-blocking file handles detected: %s' % ', '.join(_io for _io in handles))
check_blocking_io()
def initialize_locale():
"""Set the locale to the users default setting and ensure
the locale and filesystem encoding are UTF-8.
"""
try:
locale.setlocale(locale.LC_ALL, '')
dummy, encoding = locale.getlocale()
except (locale.Error, ValueError) as e:
raise SystemExit(
'ERROR: Ansible could not initialize the preferred locale: %s' % e
)
if not encoding or encoding.lower() not in ('utf-8', 'utf8'):
raise SystemExit('ERROR: Ansible requires the locale encoding to be UTF-8; Detected %s.' % encoding)
fs_enc = sys.getfilesystemencoding()
if fs_enc.lower() != 'utf-8':
raise SystemExit('ERROR: Ansible requires the filesystem encoding to be UTF-8; Detected %s.' % fs_enc)
initialize_locale()
import atexit
import errno
import getpass
import subprocess
import traceback
from abc import ABC, abstractmethod
from pathlib import Path
from ansible import _internal # do not remove or defer; ensures controller-specific state is set early
_internal.setup()
from ansible.errors import AnsibleError, ExitCode
try:
from ansible import constants as C
from ansible.utils.display import Display
display = Display()
except Exception as ex:
if isinstance(ex, AnsibleError):
ex_msg = ' '.join((ex.message, ex._help_text)).strip()
else:
ex_msg = str(ex)
print(f'ERROR: {ex_msg}\n\n{"".join(traceback.format_exception(ex))}', file=sys.stderr)
sys.exit(5)
from ansible import context
from ansible.utils import display as _display
from ansible.cli.arguments import option_helpers as opt_help
from ansible.inventory.manager import InventoryManager
from ansible.module_utils.six import string_types
from ansible.module_utils.common.text.converters import to_bytes, to_text
from ansible.module_utils.common.collections import is_sequence
from ansible.module_utils.common.file import is_executable
from ansible.module_utils.common.process import get_bin_path
from ansible.parsing.dataloader import DataLoader
from ansible.parsing.vault import PromptVaultSecret, get_file_vault_secret, VaultSecretsContext
from ansible.plugins.loader import add_all_plugin_dirs, init_plugin_loader
from ansible.release import __version__
from ansible.utils._ssh_agent import SshAgentClient
from ansible.utils.collection_loader import AnsibleCollectionConfig
from ansible.utils.collection_loader._collection_finder import _get_collection_name_from_path
from ansible.utils.path import unfrackpath
from ansible.vars.manager import VariableManager
from ansible.module_utils._internal import _deprecator
try:
import argcomplete
HAS_ARGCOMPLETE = True
except ImportError:
HAS_ARGCOMPLETE = False
_SSH_AGENT_STDOUT_READ_TIMEOUT = 5 # seconds
def _ssh_agent_timeout_handler(signum, frame):
raise TimeoutError
def _launch_ssh_agent() -> None:
ssh_agent_cfg = C.config.get_config_value('SSH_AGENT')
match ssh_agent_cfg:
case 'none':
display.debug('SSH_AGENT set to none')
return
case 'auto':
try:
ssh_agent_bin = get_bin_path('ssh-agent')
except ValueError as e:
raise AnsibleError('SSH_AGENT set to auto, but cannot find ssh-agent binary') from e
ssh_agent_dir = os.path.join(C.DEFAULT_LOCAL_TMP, 'ssh_agent')
os.mkdir(ssh_agent_dir, 0o700)
sock = os.path.join(ssh_agent_dir, 'agent.sock')
display.vvv('SSH_AGENT: starting...')
try:
p = subprocess.Popen(
[ssh_agent_bin, '-D', '-s', '-a', sock],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
except OSError as e:
raise AnsibleError(
f'Could not start ssh-agent: {e}'
) from e
if p.poll() is not None:
raise AnsibleError(
f'Could not start ssh-agent: rc={p.returncode} stderr="{p.stderr.read().decode()}"'
)
old_sigalrm_handler = signal.signal(signal.SIGALRM, _ssh_agent_timeout_handler)
signal.alarm(_SSH_AGENT_STDOUT_READ_TIMEOUT)
try:
stdout = p.stdout.read(13)
except TimeoutError:
stdout = b''
finally:
signal.alarm(0)
signal.signal(signal.SIGALRM, old_sigalrm_handler)
if stdout != b'SSH_AUTH_SOCK':
display.warning(
f'The first 13 characters of stdout did not match the '
f'expected SSH_AUTH_SOCK. This may not be the right binary, '
f'or an incompatible agent: {stdout.decode()}'
)
display.vvv(f'SSH_AGENT: ssh-agent[{p.pid}] started and bound to {sock}')
atexit.register(p.terminate)
case _:
sock = ssh_agent_cfg
try:
with SshAgentClient(sock) as client:
client.list()
except Exception as e:
raise AnsibleError(
f'Could not communicate with ssh-agent using auth sock {sock}: {e}'
) from e
os.environ['SSH_AUTH_SOCK'] = os.environ['ANSIBLE_SSH_AGENT'] = sock
class CLI(ABC):
""" code behind bin/ansible* programs """
PAGER = C.config.get_config_value('PAGER')
# -F (quit-if-one-screen) -R (allow raw ansi control chars)
# -S (chop long lines) -X (disable termcap init and de-init)
LESS_OPTS = 'FRSX'
SKIP_INVENTORY_DEFAULTS = False
USES_CONNECTION = False
def __init__(self, args, callback=None):
"""
Base init method for all command line programs
"""
if not args:
raise ValueError('A non-empty list for args is required')
self.args = args
self.parser = None
self.callback = callback
self.show_devel_warning()
def show_devel_warning(self) -> None:
if C.DEVEL_WARNING and __version__.endswith('dev0'):
display.warning(
'You are running the development version of Ansible. You should only run Ansible from "devel" if '
'you are modifying the Ansible engine, or trying out features under development. This is a rapidly '
'changing source of code and can become unstable at any point.'
)
@abstractmethod
def run(self):
"""Run the ansible command
Subclasses must implement this method. It does the actual work of
running an Ansible command.
"""
self.parse()
# Initialize plugin loader after parse, so that the init code can utilize parsed arguments
cli_collections_path = context.CLIARGS.get('collections_path') or []
if not is_sequence(cli_collections_path):
# In some contexts ``collections_path`` is singular
cli_collections_path = [cli_collections_path]
init_plugin_loader(cli_collections_path)
display.vv(to_text(opt_help.version(self.parser.prog)))
if C.CONFIG_FILE:
display.v(u"Using %s as config file" % to_text(C.CONFIG_FILE))
else:
display.v(u"No config file found; using defaults")
_display._report_config_warnings(_deprecator.ANSIBLE_CORE_DEPRECATOR)
@staticmethod
def split_vault_id(vault_id):
# return (before_@, after_@)
# if no @, return whole string as after_
if '@' not in vault_id:
return (None, vault_id)
parts = vault_id.split('@', 1)
ret = tuple(parts)
return ret
@staticmethod
def build_vault_ids(vault_ids, vault_password_files=None,
ask_vault_pass=None, auto_prompt=True):
vault_password_files = vault_password_files or []
vault_ids = vault_ids or []
# convert vault_password_files into vault_ids slugs
for password_file in vault_password_files:
id_slug = u'%s@%s' % (C.DEFAULT_VAULT_IDENTITY, password_file)
# note this makes --vault-id higher precedence than --vault-password-file
# if we want to intertwingle them in order probably need a cli callback to populate vault_ids
# used by --vault-id and --vault-password-file
vault_ids.append(id_slug)
# if an action needs an encrypt password (create_new_password=True) and we dont
# have other secrets setup, then automatically add a password prompt as well.
# prompts cant/shouldnt work without a tty, so dont add prompt secrets
if ask_vault_pass or (not vault_ids and auto_prompt):
id_slug = u'%s@%s' % (C.DEFAULT_VAULT_IDENTITY, u'prompt_ask_vault_pass')
vault_ids.append(id_slug)
return vault_ids
@staticmethod
def setup_vault_secrets(loader, vault_ids, vault_password_files=None,
ask_vault_pass=None, create_new_password=False,
auto_prompt=True, initialize_context=True):
# list of tuples
vault_secrets = []
# Depending on the vault_id value (including how --ask-vault-pass / --vault-password-file create a vault_id)
# we need to show different prompts. This is for compat with older Towers that expect a
# certain vault password prompt format, so 'promp_ask_vault_pass' vault_id gets the old format.
prompt_formats = {}
# If there are configured default vault identities, they are considered 'first'
# so we prepend them to vault_ids (from cli) here
vault_password_files = vault_password_files or []
if C.DEFAULT_VAULT_PASSWORD_FILE:
vault_password_files.append(C.DEFAULT_VAULT_PASSWORD_FILE)
if create_new_password:
prompt_formats['prompt'] = ['New vault password (%(vault_id)s): ',
'Confirm new vault password (%(vault_id)s): ']
# 2.3 format prompts for --ask-vault-pass
prompt_formats['prompt_ask_vault_pass'] = ['New Vault password: ',
'Confirm New Vault password: ']
else:
prompt_formats['prompt'] = ['Vault password (%(vault_id)s): ']
# The format when we use just --ask-vault-pass needs to match 'Vault password:\s*?$'
prompt_formats['prompt_ask_vault_pass'] = ['Vault password: ']
vault_ids = CLI.build_vault_ids(vault_ids,
vault_password_files,
ask_vault_pass,
auto_prompt=auto_prompt)
last_exception = found_vault_secret = None
for vault_id_slug in vault_ids:
vault_id_name, vault_id_value = CLI.split_vault_id(vault_id_slug)
if vault_id_value in ['prompt', 'prompt_ask_vault_pass']:
# --vault-id some_name@prompt_ask_vault_pass --vault-id other_name@prompt_ask_vault_pass will be a little
# confusing since it will use the old format without the vault id in the prompt
built_vault_id = vault_id_name or C.DEFAULT_VAULT_IDENTITY
# choose the prompt based on --vault-id=prompt or --ask-vault-pass. --ask-vault-pass
# always gets the old format for Tower compatibility.
# ie, we used --ask-vault-pass, so we need to use the old vault password prompt
# format since Tower needs to match on that format.
prompted_vault_secret = PromptVaultSecret(prompt_formats=prompt_formats[vault_id_value],
vault_id=built_vault_id)
# a empty or invalid password from the prompt will warn and continue to the next
# without erroring globally
try:
prompted_vault_secret.load()
except AnsibleError as exc:
display.warning('Error in vault password prompt (%s): %s' % (vault_id_name, exc))
raise
found_vault_secret = True
vault_secrets.append((built_vault_id, prompted_vault_secret))
# update loader with new secrets incrementally, so we can load a vault password
# that is encrypted with a vault secret provided earlier
loader.set_vault_secrets(vault_secrets)
continue
# assuming anything else is a password file
display.vvvvv('Reading vault password file: %s' % vault_id_value)
# read vault_pass from a file
try:
file_vault_secret = get_file_vault_secret(filename=vault_id_value,
vault_id=vault_id_name,
loader=loader)
except AnsibleError as exc:
display.warning('Error getting vault password file (%s): %s' % (vault_id_name, to_text(exc)))
last_exception = exc
continue
try:
file_vault_secret.load()
except AnsibleError as exc:
display.warning('Error in vault password file loading (%s): %s' % (vault_id_name, to_text(exc)))
last_exception = exc
continue
found_vault_secret = True
if vault_id_name:
vault_secrets.append((vault_id_name, file_vault_secret))
else:
vault_secrets.append((C.DEFAULT_VAULT_IDENTITY, file_vault_secret))
# update loader with as-yet-known vault secrets
loader.set_vault_secrets(vault_secrets)
# An invalid or missing password file will error globally
# if no valid vault secret was found.
if last_exception and not found_vault_secret:
raise last_exception
if initialize_context:
VaultSecretsContext.initialize(VaultSecretsContext(vault_secrets))
return vault_secrets
@staticmethod
def _get_secret(prompt: str) -> str:
return getpass.getpass(prompt=prompt)
@staticmethod
def ask_passwords():
""" prompt for connection and become passwords if needed """
op = context.CLIARGS
sshpass = None
becomepass = None
become_prompt_method = "BECOME" if C.AGNOSTIC_BECOME_PROMPT else op['become_method'].upper()
try:
become_prompt = "%s password: " % become_prompt_method
if op['ask_pass']:
sshpass = CLI._get_secret("SSH password: ")
become_prompt = "%s password[defaults to SSH password]: " % become_prompt_method
elif op['connection_password_file']:
sshpass = CLI.get_password_from_file(op['connection_password_file'])
if op['become_ask_pass']:
becomepass = CLI._get_secret(become_prompt)
if op['ask_pass'] and becomepass == '':
becomepass = sshpass
elif op['become_password_file']:
becomepass = CLI.get_password_from_file(op['become_password_file'])
except EOFError:
pass
return sshpass, becomepass
def validate_conflicts(self, op, runas_opts=False, fork_opts=False):
""" check for conflicting options """
if fork_opts:
if op.forks < 1:
self.parser.error("The number of processes (--forks) must be >= 1")
return op
@abstractmethod
def init_parser(self, usage="", desc=None, epilog=None):
"""
Create an options parser for most ansible scripts
Subclasses need to implement this method. They will usually call the base class's
init_parser to create a basic version and then add their own options on top of that.
An implementation will look something like this::
def init_parser(self):
super(MyCLI, self).init_parser(usage="My Ansible CLI", inventory_opts=True)
ansible.arguments.option_helpers.add_runas_options(self.parser)
self.parser.add_option('--my-option', dest='my_option', action='store')
"""
self.parser = opt_help.create_base_parser(self.name, usage=usage, desc=desc, epilog=epilog)
@abstractmethod
def post_process_args(self, options):
"""Process the command line args
Subclasses need to implement this method. This method validates and transforms the command
line arguments. It can be used to check whether conflicting values were given, whether filenames
exist, etc.
An implementation will look something like this::
def post_process_args(self, options):
options = super(MyCLI, self).post_process_args(options)
if options.addition and options.subtraction:
raise AnsibleOptionsError('Only one of --addition and --subtraction can be specified')
if isinstance(options.listofhosts, string_types):
options.listofhosts = string_types.split(',')
return options
"""
# process tags
if hasattr(options, 'tags') and not options.tags:
# optparse defaults does not do what's expected
# More specifically, we want `--tags` to be additive. So we cannot
# simply change C.TAGS_RUN's default to ["all"] because then passing
# --tags foo would cause us to have ['all', 'foo']
options.tags = ['all']
if hasattr(options, 'tags') and options.tags:
tags = set()
for tag_set in options.tags:
for tag in tag_set.split(u','):
tags.add(tag.strip())
options.tags = list(tags)
# process skip_tags
if hasattr(options, 'skip_tags') and options.skip_tags:
skip_tags = set()
for tag_set in options.skip_tags:
for tag in tag_set.split(u','):
skip_tags.add(tag.strip())
options.skip_tags = list(skip_tags)
# Make sure path argument doesn't have a backslash
if hasattr(options, 'action') and options.action in ['install', 'download'] and hasattr(options, 'args'):
options.args = [path.rstrip("/") for path in options.args]
# process inventory options except for CLIs that require their own processing
if hasattr(options, 'inventory') and not self.SKIP_INVENTORY_DEFAULTS:
if options.inventory:
# should always be list
if isinstance(options.inventory, string_types):
options.inventory = [options.inventory]
# Ensure full paths when needed
options.inventory = [unfrackpath(opt, follow=False) if ',' not in opt else opt for opt in options.inventory]
else:
options.inventory = C.DEFAULT_HOST_LIST
return options
def parse(self):
"""Parse the command line args
This method parses the command line arguments. It uses the parser
stored in the self.parser attribute and saves the args and options in
context.CLIARGS.
Subclasses need to implement two helper methods, init_parser() and post_process_args() which
are called from this function before and after parsing the arguments.
"""
self.init_parser()
if HAS_ARGCOMPLETE:
argcomplete.autocomplete(self.parser)
try:
options = self.parser.parse_args(self.args[1:])
except SystemExit as ex:
if ex.code != 0:
self.parser.exit(status=2, message=" \n%s" % self.parser.format_help())
raise
options = self.post_process_args(options)
context._init_global_context(options)
@staticmethod
def version_info(gitinfo=False):
""" return full ansible version info """
if gitinfo:
# expensive call, user with care
ansible_version_string = opt_help.version()
else:
ansible_version_string = __version__
ansible_version = ansible_version_string.split()[0]
ansible_versions = ansible_version.split('.')
for counter in range(len(ansible_versions)):
if ansible_versions[counter] == "":
ansible_versions[counter] = 0
try:
ansible_versions[counter] = int(ansible_versions[counter])
except Exception:
pass
if len(ansible_versions) < 3:
for counter in range(len(ansible_versions), 3):
ansible_versions.append(0)
return {'string': ansible_version_string.strip(),
'full': ansible_version,
'major': ansible_versions[0],
'minor': ansible_versions[1],
'revision': ansible_versions[2]}
@staticmethod
def pager(text):
""" find reasonable way to display text """
# this is a much simpler form of what is in pydoc.py
if not sys.stdout.isatty():
display.display(text, screen_only=True)
elif CLI.PAGER:
if sys.platform == 'win32':
display.display(text, screen_only=True)
else:
CLI.pager_pipe(text)
else:
p = subprocess.Popen('less --version', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.communicate()
if p.returncode == 0:
CLI.pager_pipe(text, 'less')
else:
display.display(text, screen_only=True)
@staticmethod
def pager_pipe(text):
""" pipe text through a pager """
if 'less' in CLI.PAGER:
os.environ['LESS'] = CLI.LESS_OPTS
try:
cmd = subprocess.Popen(CLI.PAGER, shell=True, stdin=subprocess.PIPE, stdout=sys.stdout)
cmd.communicate(input=to_bytes(text))
except IOError:
pass
except KeyboardInterrupt:
pass
def _play_prereqs(self):
# TODO: evaluate moving all of the code that touches ``AnsibleCollectionConfig``
# into ``init_plugin_loader`` so that we can specifically remove
# ``AnsibleCollectionConfig.playbook_paths`` to make it immutable after instantiation
options = context.CLIARGS
# all needs loader
loader = DataLoader()
basedir = options.get('basedir', False)
if basedir:
loader.set_basedir(basedir)
add_all_plugin_dirs(basedir)
AnsibleCollectionConfig.playbook_paths = basedir
default_collection = _get_collection_name_from_path(basedir)
if default_collection:
display.warning(u'running with default collection {0}'.format(default_collection))
AnsibleCollectionConfig.default_collection = default_collection
vault_ids = list(options['vault_ids'])
default_vault_ids = C.DEFAULT_VAULT_IDENTITY_LIST
vault_ids = default_vault_ids + vault_ids
vault_secrets = CLI.setup_vault_secrets(loader,
vault_ids=vault_ids,
vault_password_files=list(options['vault_password_files']),
ask_vault_pass=options['ask_vault_pass'],
auto_prompt=False)
loader.set_vault_secrets(vault_secrets)
if self.USES_CONNECTION:
try:
_launch_ssh_agent()
except Exception as e:
raise AnsibleError('Failed to launch ssh agent', orig_exc=e)
# create the inventory, and filter it based on the subset specified (if any)
inventory = InventoryManager(loader=loader, sources=options['inventory'], cache=(not options.get('flush_cache')))
# create the variable manager, which will be shared throughout
# the code, ensuring a consistent view of global variables
variable_manager = VariableManager(loader=loader, inventory=inventory, version_info=CLI.version_info(gitinfo=False))
# flush fact cache if requested
if options['flush_cache']:
CLI._flush_cache(inventory, variable_manager)
return loader, inventory, variable_manager
@staticmethod
def _flush_cache(inventory, variable_manager):
variable_manager.clear_facts('localhost')
for host in inventory.list_hosts():
hostname = host.get_name()
variable_manager.clear_facts(hostname)
@staticmethod
def get_host_list(inventory, subset, pattern='all'):
no_hosts = False
if len(inventory.list_hosts()) == 0:
# Empty inventory
if C.LOCALHOST_WARNING and pattern not in C.LOCALHOST:
display.warning("provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'")
no_hosts = True
inventory.subset(subset)
hosts = inventory.list_hosts(pattern)
if not hosts and no_hosts is False:
raise AnsibleError("Specified inventory, host pattern and/or --limit leaves us with no hosts to target.")
return hosts
@staticmethod
def get_password_from_file(pwd_file: str) -> str:
b_pwd_file = to_bytes(pwd_file)
if b_pwd_file == b'-':
# ensure its read as bytes
secret = sys.stdin.buffer.read()
elif not os.path.exists(b_pwd_file):
raise AnsibleError("The password file %s was not found" % pwd_file)
elif is_executable(b_pwd_file):
display.vvvv(u'The password file %s is a script.' % to_text(pwd_file))
cmd = [b_pwd_file]
try:
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
except OSError as e:
raise AnsibleError("Problem occurred when trying to run the password script %s (%s)."
" If this is not a script, remove the executable bit from the file." % (pwd_file, e))
stdout, stderr = p.communicate()
if p.returncode != 0:
raise AnsibleError("The password script %s returned an error (rc=%s): %s" % (pwd_file, p.returncode, to_text(stderr)))
secret = stdout
else:
try:
with open(b_pwd_file, "rb") as password_file:
secret = password_file.read().strip()
except (OSError, IOError) as e:
raise AnsibleError("Could not read password file %s: %s" % (pwd_file, e))
secret = secret.strip(b'\r\n')
if not secret:
raise AnsibleError('Empty password was provided from file (%s)' % pwd_file)
return to_text(secret)
@classmethod
def cli_executor(cls, args=None):
if args is None:
args = sys.argv
try:
display.debug("starting run")
ansible_dir = Path(C.ANSIBLE_HOME).expanduser()
try:
ansible_dir.mkdir(mode=0o700)
except OSError as exc:
if exc.errno != errno.EEXIST:
display.warning(
"Failed to create the directory '%s': %s" % (ansible_dir, to_text(exc, errors='surrogate_or_replace'))
)
else:
display.debug("Created the '%s' directory" % ansible_dir)
cli = cls(args)
exit_code = cli.run()
except AnsibleError as ex:
display.error(ex)
exit_code = ex._exit_code
except KeyboardInterrupt:
display.error("User interrupted execution")
exit_code = ExitCode.KEYBOARD_INTERRUPT
except Exception as ex:
try:
raise AnsibleError("Unexpected Exception, this is probably a bug.") from ex
except AnsibleError as ex2:
# DTFIX-RELEASE: clean this up so we're not hacking the internals- re-wrap in an AnsibleCLIUnhandledError that always shows TB, or?
from ansible.module_utils._internal import _traceback
_traceback._is_traceback_enabled = lambda *_args, **_kwargs: True
display.error(ex2)
exit_code = ExitCode.UNKNOWN_ERROR
sys.exit(exit_code)
ansible_core-2.19.0b4/lib/ansible/cli/_ssh_askpass.py 0000644 0000000 0000000 00000002525 15010426755 021212 0 ustar 00root root # Copyright: Contributors to the Ansible project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import annotations
import json
import os
import re
import sys
import typing as t
from multiprocessing.shared_memory import SharedMemory
HOST_KEY_RE = re.compile(
r'(The authenticity of host |differs from the key for the IP address)',
)
def main() -> t.Never:
try:
if HOST_KEY_RE.search(sys.argv[1]):
sys.stdout.buffer.write(b'no')
sys.stdout.flush()
sys.exit(0)
except IndexError:
pass
kwargs: dict[str, bool] = {}
if sys.version_info[:2] >= (3, 13):
# deprecated: description='unneeded due to track argument for SharedMemory' python_version='3.12'
kwargs['track'] = False
try:
shm = SharedMemory(name=os.environ['_ANSIBLE_SSH_ASKPASS_SHM'], **kwargs)
except FileNotFoundError:
# We must be running after the ansible fork is shutting down
sys.exit(1)
cfg = json.loads(shm.buf.tobytes().rstrip(b'\x00'))
try:
if cfg['prompt'] not in sys.argv[1]:
sys.exit(1)
except IndexError:
sys.exit(1)
sys.stdout.buffer.write(cfg['password'].encode('utf-8'))
sys.stdout.flush()
shm.buf[:] = b'\x00' * shm.size
shm.close()
sys.exit(0)
ansible_core-2.19.0b4/lib/ansible/cli/adhoc.py 0000755 0000000 0000000 00000020307 15010426755 017610 0 ustar 00root root #!/usr/bin/env python
# Copyright: (c) 2012, Michael DeHaan
# Copyright: (c) 2018, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# PYTHON_ARGCOMPLETE_OK
from __future__ import annotations
import json
# ansible.cli needs to be imported first, to ensure the source bin/* scripts run that code first
from ansible.cli import CLI
from ansible import constants as C
from ansible import context
from ansible.cli.arguments import option_helpers as opt_help
from ansible.errors import AnsibleError, AnsibleOptionsError, AnsibleParserError
from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.module_utils.common.text.converters import to_text
from ansible.parsing.splitter import parse_kv
from ansible.playbook import Playbook
from ansible.playbook.play import Play
from ansible._internal._datatag._tags import Origin
from ansible.utils.display import Display
from ansible._internal._json._profiles import _legacy
display = Display()
class AdHocCLI(CLI):
""" is an extra-simple tool/framework/API for doing 'remote things'.
this command allows you to define and run a single task 'playbook' against a set of hosts
"""
name = 'ansible'
USES_CONNECTION = True
def init_parser(self):
""" create an options parser for bin/ansible """
super(AdHocCLI, self).init_parser(usage='%prog [options]',
desc="Define and run a single task 'playbook' against a set of hosts",
epilog="Some actions do not make sense in Ad-Hoc (include, meta, etc)")
opt_help.add_runas_options(self.parser)
opt_help.add_inventory_options(self.parser)
opt_help.add_async_options(self.parser)
opt_help.add_output_options(self.parser)
opt_help.add_connect_options(self.parser)
opt_help.add_check_options(self.parser)
opt_help.add_runtask_options(self.parser)
opt_help.add_vault_options(self.parser)
opt_help.add_fork_options(self.parser)
opt_help.add_module_options(self.parser)
opt_help.add_basedir_options(self.parser)
opt_help.add_tasknoplay_options(self.parser)
# options unique to ansible ad-hoc
self.parser.add_argument('-a', '--args', dest='module_args',
help="The action's options in space separated k=v format: -a 'opt1=val1 opt2=val2' "
"or a json string: -a '{\"opt1\": \"val1\", \"opt2\": \"val2\"}'",
default=C.DEFAULT_MODULE_ARGS)
self.parser.add_argument('-m', '--module-name', dest='module_name',
help="Name of the action to execute (default=%s)" % C.DEFAULT_MODULE_NAME,
default=C.DEFAULT_MODULE_NAME)
self.parser.add_argument('args', metavar='pattern', help='host pattern')
def post_process_args(self, options):
"""Post process and validate options for bin/ansible """
options = super(AdHocCLI, self).post_process_args(options)
display.verbosity = options.verbosity
self.validate_conflicts(options, runas_opts=True, fork_opts=True)
return options
def _play_ds(self, pattern, async_val, poll):
check_raw = context.CLIARGS['module_name'] in C.MODULE_REQUIRE_ARGS
module_args_raw = context.CLIARGS['module_args']
module_args = None
if module_args_raw and module_args_raw.startswith('{') and module_args_raw.endswith('}'):
try:
module_args = json.loads(module_args_raw, cls=_legacy.Decoder)
except AnsibleParserError:
pass
if not module_args:
module_args = parse_kv(module_args_raw, check_raw=check_raw)
mytask = {'action': {'module': context.CLIARGS['module_name'], 'args': module_args},
'timeout': context.CLIARGS['task_timeout']}
mytask = Origin(description=f'').tag(mytask)
# avoid adding to tasks that don't support it, unless set, then give user an error
if context.CLIARGS['module_name'] not in C._ACTION_ALL_INCLUDE_ROLE_TASKS and any(frozenset((async_val, poll))):
mytask['async_val'] = async_val
mytask['poll'] = poll
return dict(
name="Ansible Ad-Hoc",
hosts=pattern,
gather_facts='no',
tasks=[mytask])
def run(self):
""" create and execute the single task playbook """
super(AdHocCLI, self).run()
# only thing left should be host pattern
pattern = to_text(context.CLIARGS['args'], errors='surrogate_or_strict')
# handle password prompts
sshpass = None
becomepass = None
(sshpass, becomepass) = self.ask_passwords()
passwords = {'conn_pass': sshpass, 'become_pass': becomepass}
# get basic objects
loader, inventory, variable_manager = self._play_prereqs()
# get list of hosts to execute against
try:
hosts = self.get_host_list(inventory, context.CLIARGS['subset'], pattern)
except AnsibleError:
if context.CLIARGS['subset']:
raise
else:
hosts = []
display.warning("No hosts matched, nothing to do")
# just listing hosts?
if context.CLIARGS['listhosts']:
display.display(' hosts (%d):' % len(hosts))
for host in hosts:
display.display(' %s' % host)
return 0
# verify we have arguments if we know we need em
if context.CLIARGS['module_name'] in C.MODULE_REQUIRE_ARGS and not context.CLIARGS['module_args']:
err = "No argument passed to %s module" % context.CLIARGS['module_name']
if pattern.endswith(".yml"):
err = err + ' (did you mean to run ansible-playbook?)'
raise AnsibleOptionsError(err)
# Avoid modules that don't work with ad-hoc
if context.CLIARGS['module_name'] in C._ACTION_IMPORT_PLAYBOOK:
raise AnsibleOptionsError("'%s' is not a valid action for ad-hoc commands"
% context.CLIARGS['module_name'])
# construct playbook objects to wrap task
play_ds = self._play_ds(pattern, context.CLIARGS['seconds'], context.CLIARGS['poll_interval'])
play = Play().load(play_ds, variable_manager=variable_manager, loader=loader)
# used in start callback
playbook = Playbook(loader)
playbook._entries.append(play)
playbook._file_name = '__adhoc_playbook__'
if self.callback:
cb = self.callback
elif context.CLIARGS['one_line']:
cb = 'oneline'
# Respect custom 'stdout_callback' only with enabled 'bin_ansible_callbacks'
elif C.DEFAULT_LOAD_CALLBACK_PLUGINS and C.DEFAULT_STDOUT_CALLBACK != 'default':
cb = C.DEFAULT_STDOUT_CALLBACK
else:
cb = 'minimal'
run_tree = False
if context.CLIARGS['tree']:
C.CALLBACKS_ENABLED.append('tree')
C.TREE_DIR = context.CLIARGS['tree']
run_tree = True
# now create a task queue manager to execute the play
self._tqm = None
try:
self._tqm = TaskQueueManager(
inventory=inventory,
variable_manager=variable_manager,
loader=loader,
passwords=passwords,
stdout_callback=cb,
run_additional_callbacks=C.DEFAULT_LOAD_CALLBACK_PLUGINS,
run_tree=run_tree,
forks=context.CLIARGS['forks'],
)
self._tqm.load_callbacks()
self._tqm.send_callback('v2_playbook_on_start', playbook)
result = self._tqm.run(play)
self._tqm.send_callback('v2_playbook_on_stats', self._tqm._stats)
finally:
if self._tqm:
self._tqm.cleanup()
if loader:
loader.cleanup_all_tmp_files()
return result
def main(args=None):
AdHocCLI.cli_executor(args)
if __name__ == '__main__':
main()
ansible_core-2.19.0b4/lib/ansible/cli/arguments/ 0000755 0000000 0000000 00000000000 15010426755 020160 5 ustar 00root root ansible_core-2.19.0b4/lib/ansible/cli/arguments/__init__.py 0000644 0000000 0000000 00000000250 15010426755 022266 0 ustar 00root root # Copyright: (c) 2018, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import annotations
ansible_core-2.19.0b4/lib/ansible/cli/arguments/option_helpers.py 0000644 0000000 0000000 00000057575 15010426755 023607 0 ustar 00root root # Copyright: (c) 2018, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import annotations
import copy
import dataclasses
import inspect
import operator
import argparse
import os
import os.path
import sys
import time
import typing as t
import yaml
from jinja2 import __version__ as j2_version
import ansible
from ansible import constants as C
from ansible.module_utils.common.text.converters import to_native
from ansible.module_utils.common.yaml import HAS_LIBYAML, yaml_load
from ansible.release import __version__
from ansible.utils.path import unfrackpath
from ansible._internal._datatag._tags import TrustedAsTemplate, Origin
#
# Special purpose OptionParsers
#
class SortingHelpFormatter(argparse.HelpFormatter):
def add_arguments(self, actions):
actions = sorted(actions, key=operator.attrgetter('option_strings'))
super(SortingHelpFormatter, self).add_arguments(actions)
@dataclasses.dataclass(frozen=True, kw_only=True)
class DeprecatedArgument:
version: str
"""The Ansible version that will remove the deprecated argument."""
option: str | None = None
"""The specific option string that is deprecated; None applies to all options for this argument."""
def is_deprecated(self, option: str) -> bool:
"""Return True if the given option is deprecated, otherwise False."""
return self.option is None or option == self.option
def check(self, option: str) -> None:
"""Display a deprecation warning if the given option is deprecated."""
if not self.is_deprecated(option):
return
from ansible.utils.display import Display
Display().deprecated( # pylint: disable=ansible-invalid-deprecated-version
msg=f'The {option!r} argument is deprecated.',
version=self.version,
)
class ArgumentParser(argparse.ArgumentParser):
def __init__(self, *args, **kwargs) -> None:
self.__actions: dict[str | None, type[argparse.Action]] = {}
super().__init__(*args, **kwargs)
def register(self, registry_name, value, object):
"""Track registration of actions so that they can be resolved later by name, without depending on the internals of ArgumentParser."""
if registry_name == 'action':
self.__actions[value] = object
super().register(registry_name, value, object)
def _patch_argument(self, args: tuple[str, ...], kwargs: dict[str, t.Any]) -> None:
"""
Patch `kwargs` for an `add_argument` call using the given `args` and `kwargs`.
This is used to apply tags to entire categories of CLI arguments.
"""
name = args[0]
action = kwargs.get('action')
resolved_action = self.__actions.get(action, action) # get the action by name, or use as-is (assume it's a subclass of argparse.Action)
action_signature = inspect.signature(resolved_action.__init__)
if action_signature.parameters.get('type'):
arg_type = kwargs.get('type', str)
if not callable(arg_type):
raise ValueError(f'Argument {name!r} requires a callable for the {"type"!r} parameter, not {arg_type!r}.')
wrapped_arg_type = _tagged_type_factory(name, arg_type)
kwargs.update(type=wrapped_arg_type)
def _patch_parser(self, parser):
"""Patch and return the given parser to intercept the `add_argument` method for further patching."""
parser_add_argument = parser.add_argument
def add_argument(*ag_args, **ag_kwargs):
self._patch_argument(ag_args, ag_kwargs)
parser_add_argument(*ag_args, **ag_kwargs)
parser.add_argument = add_argument
return parser
def add_subparsers(self, *args, **kwargs):
sub = super().add_subparsers(*args, **kwargs)
sub_add_parser = sub.add_parser
def add_parser(*sub_args, **sub_kwargs):
return self._patch_parser(sub_add_parser(*sub_args, **sub_kwargs))
sub.add_parser = add_parser
return sub
def add_argument_group(self, *args, **kwargs):
return self._patch_parser(super().add_argument_group(*args, **kwargs))
def add_mutually_exclusive_group(self, *args, **kwargs):
return self._patch_parser(super().add_mutually_exclusive_group(*args, **kwargs))
def add_argument(self, *args, **kwargs) -> argparse.Action:
action = kwargs.get('action')
help = kwargs.get('help')
if help and action in {'append', 'append_const', 'count', 'extend', PrependListAction}:
help = f'{help.rstrip(".")}. This argument may be specified multiple times.'
kwargs['help'] = help
self._patch_argument(args, kwargs)
deprecated: DeprecatedArgument | None
if deprecated := kwargs.pop('deprecated', None):
action_type = self.__actions.get(action, action)
class DeprecatedAction(action_type): # type: ignore[misc, valid-type]
"""A wrapper around an action which handles deprecation warnings."""
def __call__(self, parser, namespace, values, option_string=None) -> t.Any:
deprecated.check(option_string)
return super().__call__(parser, namespace, values, option_string)
kwargs['action'] = DeprecatedAction
return super().add_argument(*args, **kwargs)
class AnsibleVersion(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None):
ansible_version = to_native(version(getattr(parser, 'prog')))
print(ansible_version)
parser.exit()
class UnrecognizedArgument(argparse.Action):
def __init__(self, option_strings, dest, const=True, default=None, required=False, help=None, metavar=None, nargs=0):
super(UnrecognizedArgument, self).__init__(option_strings=option_strings, dest=dest, nargs=nargs, const=const,
default=default, required=required, help=help)
def __call__(self, parser, namespace, values, option_string=None):
parser.error('unrecognized arguments: %s' % option_string)
class PrependListAction(argparse.Action):
"""A near clone of ``argparse._AppendAction``, but designed to prepend list values
instead of appending.
"""
def __init__(self, option_strings, dest, nargs=None, const=None, default=None, type=None,
choices=None, required=False, help=None, metavar=None):
if nargs == 0:
raise ValueError('nargs for append actions must be > 0; if arg '
'strings are not supplying the value to append, '
'the append const action may be more appropriate')
if const is not None and nargs != argparse.OPTIONAL:
raise ValueError('nargs must be %r to supply const' % argparse.OPTIONAL)
super(PrependListAction, self).__init__(
option_strings=option_strings,
dest=dest,
nargs=nargs,
const=const,
default=default,
type=type,
choices=choices,
required=required,
help=help,
metavar=metavar
)
def __call__(self, parser, namespace, values, option_string=None):
items = copy.copy(ensure_value(namespace, self.dest, []))
items[0:0] = values
setattr(namespace, self.dest, items)
def ensure_value(namespace, name, value):
if getattr(namespace, name, None) is None:
setattr(namespace, name, value)
return getattr(namespace, name)
#
# Callbacks to validate and normalize Options
#
def unfrack_path(pathsep=False, follow=True):
"""Turn an Option's data into a single path in Ansible locations"""
def inner(value):
if pathsep:
return [unfrackpath(x, follow=follow) for x in value.split(os.pathsep) if x]
if value == '-':
return value
return unfrackpath(value, follow=follow)
return inner
def maybe_unfrack_path(beacon):
def inner(value):
if value.startswith(beacon):
return beacon + unfrackpath(value[1:])
return value
return inner
def _git_repo_info(repo_path):
""" returns a string containing git branch, commit id and commit date """
result = None
if os.path.exists(repo_path):
# Check if the .git is a file. If it is a file, it means that we are in a submodule structure.
if os.path.isfile(repo_path):
try:
with open(repo_path) as f:
gitdir = yaml_load(f).get('gitdir')
# There is a possibility the .git file to have an absolute path.
if os.path.isabs(gitdir):
repo_path = gitdir
else:
repo_path = os.path.join(repo_path[:-4], gitdir)
except (IOError, AttributeError):
return ''
with open(os.path.join(repo_path, "HEAD")) as f:
line = f.readline().rstrip("\n")
if line.startswith("ref:"):
branch_path = os.path.join(repo_path, line[5:])
else:
branch_path = None
if branch_path and os.path.exists(branch_path):
branch = '/'.join(line.split('/')[2:])
with open(branch_path) as f:
commit = f.readline()[:10]
else:
# detached HEAD
commit = line[:10]
branch = 'detached HEAD'
branch_path = os.path.join(repo_path, "HEAD")
date = time.localtime(os.stat(branch_path).st_mtime)
if time.daylight == 0:
offset = time.timezone
else:
offset = time.altzone
result = "({0} {1}) last updated {2} (GMT {3:+04d})".format(branch, commit, time.strftime("%Y/%m/%d %H:%M:%S", date), int(offset / -36))
else:
result = ''
return result
def _gitinfo():
basedir = os.path.normpath(os.path.join(os.path.dirname(__file__), '..', '..', '..', '..'))
repo_path = os.path.join(basedir, '.git')
return _git_repo_info(repo_path)
def version(prog=None):
""" return ansible version """
if prog:
result = ["{0} [core {1}]".format(prog, __version__)]
else:
result = [__version__]
gitinfo = _gitinfo()
if gitinfo:
result[0] = "{0} {1}".format(result[0], gitinfo)
result.append(" config file = %s" % C.CONFIG_FILE)
if C.DEFAULT_MODULE_PATH is None:
cpath = "Default w/o overrides"
else:
cpath = C.DEFAULT_MODULE_PATH
if HAS_LIBYAML:
libyaml_fragment = "with libyaml"
# noinspection PyBroadException
try:
from yaml._yaml import get_version_string
libyaml_fragment += f" v{get_version_string()}"
except Exception: # pylint: disable=broad-except
libyaml_fragment += ", version unknown"
else:
libyaml_fragment = "without libyaml"
result.append(" configured module search path = %s" % cpath)
result.append(" ansible python module location = %s" % ':'.join(ansible.__path__))
result.append(" ansible collection location = %s" % ':'.join(C.COLLECTIONS_PATHS))
result.append(" executable location = %s" % sys.argv[0])
result.append(" python version = %s (%s)" % (''.join(sys.version.splitlines()), to_native(sys.executable)))
result.append(" jinja version = %s" % j2_version)
result.append(f" pyyaml version = {yaml.__version__} ({libyaml_fragment})")
return "\n".join(result)
#
# Functions to add pre-canned options to an OptionParser
#
def create_base_parser(prog, usage="", desc=None, epilog=None):
"""
Create an options parser for all ansible scripts
"""
# base opts
parser = ArgumentParser(
prog=prog,
formatter_class=SortingHelpFormatter,
epilog=epilog,
description=desc,
conflict_handler='resolve',
)
version_help = "show program's version number, config file location, configured module search path," \
" module location, executable location and exit"
parser.add_argument('--version', action=AnsibleVersion, nargs=0, help=version_help)
add_verbosity_options(parser)
return parser
def add_verbosity_options(parser):
"""Add options for verbosity"""
parser.add_argument('-v', '--verbose', dest='verbosity', default=C.DEFAULT_VERBOSITY, action="count",
help="Causes Ansible to print more debug messages. Adding multiple -v will increase the verbosity, "
"the builtin plugins currently evaluate up to -vvvvvv. A reasonable level to start is -vvv, "
"connection debugging might require -vvvv.")
def add_async_options(parser):
"""Add options for commands which can launch async tasks"""
parser.add_argument('-P', '--poll', default=C.DEFAULT_POLL_INTERVAL, type=int, dest='poll_interval',
help="set the poll interval if using -B (default=%s)" % C.DEFAULT_POLL_INTERVAL)
parser.add_argument('-B', '--background', dest='seconds', type=int, default=0,
help='run asynchronously, failing after X seconds (default=N/A)')
def add_basedir_options(parser):
"""Add options for commands which can set a playbook basedir"""
parser.add_argument('--playbook-dir', default=C.PLAYBOOK_DIR, dest='basedir', action='store',
help="Since this tool does not use playbooks, use this as a substitute playbook directory. "
"This sets the relative path for many features including roles/ group_vars/ etc.",
type=unfrack_path())
def add_check_options(parser):
"""Add options for commands which can run with diagnostic information of tasks"""
parser.add_argument("-C", "--check", default=False, dest='check', action='store_true',
help="don't make any changes; instead, try to predict some of the changes that may occur")
parser.add_argument("-D", "--diff", default=C.DIFF_ALWAYS, dest='diff', action='store_true',
help="when changing (small) files and templates, show the differences in those"
" files; works great with --check")
def add_connect_options(parser):
"""Add options for commands which need to connection to other hosts"""
connect_group = parser.add_argument_group("Connection Options", "control as whom and how to connect to hosts")
connect_group.add_argument('--private-key', '--key-file', default=C.DEFAULT_PRIVATE_KEY_FILE, dest='private_key_file',
help='use this file to authenticate the connection', type=unfrack_path())
connect_group.add_argument('-u', '--user', default=C.DEFAULT_REMOTE_USER, dest='remote_user',
help='connect as this user (default=%s)' % C.DEFAULT_REMOTE_USER)
connect_group.add_argument('-c', '--connection', dest='connection', default=C.DEFAULT_TRANSPORT,
help="connection type to use (default=%s)" % C.DEFAULT_TRANSPORT)
connect_group.add_argument('-T', '--timeout', default=None, type=int, dest='timeout',
help="override the connection timeout in seconds (default depends on connection)")
# ssh only
connect_group.add_argument('--ssh-common-args', default=None, dest='ssh_common_args',
help="specify common arguments to pass to sftp/scp/ssh (e.g. ProxyCommand)")
connect_group.add_argument('--sftp-extra-args', default=None, dest='sftp_extra_args',
help="specify extra arguments to pass to sftp only (e.g. -f, -l)")
connect_group.add_argument('--scp-extra-args', default=None, dest='scp_extra_args',
help="specify extra arguments to pass to scp only (e.g. -l)")
connect_group.add_argument('--ssh-extra-args', default=None, dest='ssh_extra_args',
help="specify extra arguments to pass to ssh only (e.g. -R)")
parser.add_argument_group(connect_group)
connect_password_group = parser.add_mutually_exclusive_group()
connect_password_group.add_argument('-k', '--ask-pass', default=C.DEFAULT_ASK_PASS, dest='ask_pass', action='store_true',
help='ask for connection password')
connect_password_group.add_argument('--connection-password-file', '--conn-pass-file', default=C.CONNECTION_PASSWORD_FILE, dest='connection_password_file',
help="Connection password file", type=unfrack_path(), action='store')
parser.add_argument_group(connect_password_group)
def add_fork_options(parser):
"""Add options for commands that can fork worker processes"""
parser.add_argument('-f', '--forks', dest='forks', default=C.DEFAULT_FORKS, type=int,
help="specify number of parallel processes to use (default=%s)" % C.DEFAULT_FORKS)
def add_inventory_options(parser):
"""Add options for commands that utilize inventory"""
parser.add_argument('-i', '--inventory', '--inventory-file', dest='inventory', action="append",
help="specify inventory host path or comma separated host list",
deprecated=DeprecatedArgument(version='2.23', option='--inventory-file'))
parser.add_argument('--list-hosts', dest='listhosts', action='store_true',
help='outputs a list of matching hosts; does not execute anything else')
parser.add_argument('-l', '--limit', default=C.DEFAULT_SUBSET, dest='subset',
help='further limit selected hosts to an additional pattern')
parser.add_argument('--flush-cache', dest='flush_cache', action='store_true',
help="clear the fact cache for every host in inventory")
def add_meta_options(parser):
"""Add options for commands which can launch meta tasks from the command line"""
parser.add_argument('--force-handlers', default=C.DEFAULT_FORCE_HANDLERS, dest='force_handlers', action='store_true',
help="run handlers even if a task fails")
def add_module_options(parser):
"""Add options for commands that load modules"""
module_path = C.config.get_configuration_definition('DEFAULT_MODULE_PATH').get('default', '')
parser.add_argument('-M', '--module-path', dest='module_path', default=None,
help="prepend colon-separated path(s) to module library (default=%s)" % module_path,
type=unfrack_path(pathsep=True), action=PrependListAction)
def add_output_options(parser):
"""Add options for commands which can change their output"""
parser.add_argument('-o', '--one-line', dest='one_line', action='store_true',
help='condense output', deprecated=DeprecatedArgument(version='2.23'))
parser.add_argument('-t', '--tree', dest='tree', default=None,
help='log output to this directory', deprecated=DeprecatedArgument(version='2.23'))
def add_runas_options(parser):
"""
Add options for commands which can run tasks as another user
Note that this includes the options from add_runas_prompt_options(). Only one of these
functions should be used.
"""
runas_group = parser.add_argument_group("Privilege Escalation Options", "control how and which user you become as on target hosts")
# consolidated privilege escalation (become)
runas_group.add_argument("-b", "--become", default=C.DEFAULT_BECOME, action="store_true", dest='become',
help="run operations with become (does not imply password prompting)")
runas_group.add_argument('--become-method', dest='become_method', default=C.DEFAULT_BECOME_METHOD,
help='privilege escalation method to use (default=%s)' % C.DEFAULT_BECOME_METHOD +
', use `ansible-doc -t become -l` to list valid choices.')
runas_group.add_argument('--become-user', default=None, dest='become_user', type=str,
help='run operations as this user (default=%s)' % C.DEFAULT_BECOME_USER)
parser.add_argument_group(runas_group)
add_runas_prompt_options(parser)
def add_runas_prompt_options(parser, runas_group=None):
"""
Add options for commands which need to prompt for privilege escalation credentials
Note that add_runas_options() includes these options already. Only one of the two functions
should be used.
"""
if runas_group is not None:
parser.add_argument_group(runas_group)
runas_pass_group = parser.add_mutually_exclusive_group()
runas_pass_group.add_argument('-K', '--ask-become-pass', dest='become_ask_pass', action='store_true',
default=C.DEFAULT_BECOME_ASK_PASS,
help='ask for privilege escalation password')
runas_pass_group.add_argument('--become-password-file', '--become-pass-file', default=C.BECOME_PASSWORD_FILE, dest='become_password_file',
help="Become password file", type=unfrack_path(), action='store')
parser.add_argument_group(runas_pass_group)
def add_runtask_options(parser):
"""Add options for commands that run a task"""
parser.add_argument('-e', '--extra-vars', dest="extra_vars", action="append", type=maybe_unfrack_path('@'),
help="set additional variables as key=value or YAML/JSON, if filename prepend with @", default=[])
def add_tasknoplay_options(parser):
"""Add options for commands that run a task w/o a defined play"""
parser.add_argument('--task-timeout', type=int, dest="task_timeout", action="store", default=C.TASK_TIMEOUT,
help="set task timeout limit in seconds, must be positive integer.")
def add_subset_options(parser):
"""Add options for commands which can run a subset of tasks"""
parser.add_argument('-t', '--tags', dest='tags', default=C.TAGS_RUN, action='append',
help="only run plays and tasks tagged with these values")
parser.add_argument('--skip-tags', dest='skip_tags', default=C.TAGS_SKIP, action='append',
help="only run plays and tasks whose tags do not match these values")
def add_vault_options(parser):
"""Add options for loading vault files"""
parser.add_argument('--vault-id', default=[], dest='vault_ids', action='append', type=str,
help='the vault identity to use')
base_group = parser.add_mutually_exclusive_group()
base_group.add_argument('-J', '--ask-vault-password', '--ask-vault-pass', default=C.DEFAULT_ASK_VAULT_PASS, dest='ask_vault_pass', action='store_true',
help='ask for vault password')
base_group.add_argument('--vault-password-file', '--vault-pass-file', default=[], dest='vault_password_files',
help="vault password file", type=unfrack_path(follow=False), action='append')
def _tagged_type_factory(name: str, func: t.Callable[[str], object], /) -> t.Callable[[str], object]:
"""
Return a callable that wraps the given function.
The result of the wrapped function will be tagged with Origin.
It will also be tagged with TrustedAsTemplate if it is equal to the original input string.
"""
def tag_value(value: str) -> object:
result = func(value)
if result is value or func is str:
# Values which are not mutated are automatically trusted for templating.
# The `is` reference equality is critically important, as other types may only alter the tags, so object equality is
# not sufficient to prevent them being tagged as trusted when they should not.
# Explicitly include all usages using the `str` type factory since it strips tags.
result = TrustedAsTemplate().tag(result)
if not (origin := Origin.get_tag(value)):
origin = Origin(description=f'')
return origin.tag(result)
tag_value._name = name # simplify debugging by attaching the argument name to the function
return tag_value
ansible_core-2.19.0b4/lib/ansible/cli/config.py 0000755 0000000 0000000 00000067677 15010426755 020024 0 ustar 00root root #!/usr/bin/env python
# Copyright: (c) 2017, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# PYTHON_ARGCOMPLETE_OK
from __future__ import annotations
# ansible.cli needs to be imported first, to ensure the source bin/* scripts run that code first
from ansible.cli import CLI
import os
import shlex
import sys
import yaml
from collections.abc import Mapping
from ansible import context
import ansible.plugins.loader as plugin_loader
from ansible import constants as C
from ansible.cli.arguments import option_helpers as opt_help
from ansible.config.manager import ConfigManager
from ansible.errors import AnsibleError, AnsibleOptionsError, AnsibleRequiredOptionError
from ansible.module_utils.common.text.converters import to_native, to_text, to_bytes
from ansible._internal import _json
from ansible.module_utils.six import string_types
from ansible.parsing.quoting import is_quoted
from ansible.parsing.yaml.dumper import AnsibleDumper
from ansible.utils.color import stringc
from ansible.utils.display import Display
from ansible.utils.path import unfrackpath
display = Display()
_IGNORE_CHANGED = frozenset({'_terms', '_input'})
def yaml_dump(data, default_flow_style=False, default_style=None):
return yaml.dump(data, Dumper=AnsibleDumper, default_flow_style=default_flow_style, default_style=default_style)
def yaml_short(data):
return yaml_dump(data, default_flow_style=True, default_style="''")
def get_constants():
""" helper method to ensure we can template based on existing constants """
if not hasattr(get_constants, 'cvars'):
get_constants.cvars = {k: getattr(C, k) for k in dir(C) if not k.startswith('__')}
return get_constants.cvars
def _ansible_env_vars(varname):
""" return true or false depending if variable name is possibly a 'configurable' ansible env variable """
return all(
[
varname.startswith("ANSIBLE_"),
not varname.startswith(("ANSIBLE_TEST_", "ANSIBLE_LINT_")),
varname not in ("ANSIBLE_CONFIG", "ANSIBLE_DEV_HOME"),
]
)
def _get_evar_list(settings):
data = []
for setting in settings:
if 'env' in settings[setting] and settings[setting]['env']:
for varname in settings[setting]['env']:
data.append(varname.get('name'))
return data
def _get_ini_entries(settings):
data = {}
for setting in settings:
if 'ini' in settings[setting] and settings[setting]['ini']:
for kv in settings[setting]['ini']:
if not kv['section'] in data:
data[kv['section']] = set()
data[kv['section']].add(kv['key'])
return data
class ConfigCLI(CLI):
""" Config command line class """
name = 'ansible-config'
def __init__(self, args, callback=None):
self.config_file = None
self.config = None
super(ConfigCLI, self).__init__(args, callback)
def init_parser(self):
super(ConfigCLI, self).init_parser(
desc="View ansible configuration.",
)
common = opt_help.ArgumentParser(add_help=False)
opt_help.add_verbosity_options(common)
common.add_argument('-c', '--config', dest='config_file',
help="path to configuration file, defaults to first file found in precedence.")
common.add_argument("-t", "--type", action="store", default='base', dest='type', choices=['all', 'base'] + list(C.CONFIGURABLE_PLUGINS),
help="Filter down to a specific plugin type.")
common.add_argument('args', help='Specific plugin to target, requires type of plugin to be set', nargs='*')
subparsers = self.parser.add_subparsers(dest='action')
subparsers.required = True
list_parser = subparsers.add_parser('list', help='Print all config options', parents=[common])
list_parser.set_defaults(func=self.execute_list)
list_parser.add_argument('--format', '-f', dest='format', action='store', choices=['json', 'yaml'], default='yaml',
help='Output format for list')
dump_parser = subparsers.add_parser('dump', help='Dump configuration', parents=[common])
dump_parser.set_defaults(func=self.execute_dump)
dump_parser.add_argument('--only-changed', '--changed-only', dest='only_changed', action='store_true',
help="Only show configurations that have changed from the default")
dump_parser.add_argument('--format', '-f', dest='format', action='store', choices=['json', 'yaml', 'display'], default='display',
help='Output format for dump')
view_parser = subparsers.add_parser('view', help='View configuration file', parents=[common])
view_parser.set_defaults(func=self.execute_view)
init_parser = subparsers.add_parser('init', help='Create initial configuration', parents=[common])
init_parser.set_defaults(func=self.execute_init)
init_parser.add_argument('--format', '-f', dest='format', action='store', choices=['ini', 'env', 'vars'], default='ini',
help='Output format for init')
init_parser.add_argument('--disabled', dest='commented', action='store_true', default=False,
help='Prefixes all entries with a comment character to disable them')
validate_parser = subparsers.add_parser('validate',
help='Validate the configuration file and environment variables. '
'By default it only checks the base settings without accounting for plugins (see -t).',
parents=[common])
validate_parser.set_defaults(func=self.execute_validate)
validate_parser.add_argument('--format', '-f', dest='format', action='store', choices=['ini', 'env'] , default='ini',
help='Output format for init')
def post_process_args(self, options):
options = super(ConfigCLI, self).post_process_args(options)
display.verbosity = options.verbosity
return options
def run(self):
super(ConfigCLI, self).run()
# initialize each galaxy server's options from known listed servers
self._galaxy_servers = [s for s in C.GALAXY_SERVER_LIST or [] if s] # clean list, reused later here
C.config.load_galaxy_server_defs(self._galaxy_servers)
if context.CLIARGS['config_file']:
self.config_file = unfrackpath(context.CLIARGS['config_file'], follow=False)
b_config = to_bytes(self.config_file)
if os.path.exists(b_config) and os.access(b_config, os.R_OK):
self.config = ConfigManager(self.config_file)
else:
raise AnsibleOptionsError('The provided configuration file is missing or not accessible: %s' % to_native(self.config_file))
else:
self.config = C.config
self.config_file = self.config._config_file
if self.config_file:
try:
if not os.path.exists(self.config_file):
raise AnsibleOptionsError("%s does not exist or is not accessible" % (self.config_file))
elif not os.path.isfile(self.config_file):
raise AnsibleOptionsError("%s is not a valid file" % (self.config_file))
os.environ['ANSIBLE_CONFIG'] = to_native(self.config_file)
except Exception:
if context.CLIARGS['action'] in ['view']:
raise
elif context.CLIARGS['action'] == 'view':
raise AnsibleError('Invalid or no config file was supplied')
# run the requested action
context.CLIARGS['func']()
def execute_view(self):
"""
Displays the current config file
"""
try:
with open(self.config_file, 'rb') as f:
self.pager(to_text(f.read(), errors='surrogate_or_strict'))
except Exception as e:
raise AnsibleError("Failed to open config file: %s" % to_native(e))
def _list_plugin_settings(self, ptype, plugins=None):
entries = {}
loader = getattr(plugin_loader, '%s_loader' % ptype)
# build list
if plugins:
plugin_cs = []
for plugin in plugins:
p = loader.get(plugin, class_only=True)
if p is None:
display.warning("Skipping %s as we could not find matching plugin" % plugin)
else:
plugin_cs.append(p)
else:
plugin_cs = loader.all(class_only=True)
# iterate over class instances
for plugin in plugin_cs:
finalname = name = plugin._load_name
if name.startswith('_'):
# alias or deprecated
if os.path.islink(plugin._original_path):
continue
else:
finalname = name.replace('_', '', 1) + ' (DEPRECATED)'
entries[finalname] = self.config.get_configuration_definitions(ptype, name)
return entries
def _list_entries_from_args(self):
"""
build a dict with the list requested configs
"""
config_entries = {}
if context.CLIARGS['type'] in ('base', 'all'):
# this dumps main/common configs
config_entries = self.config.get_configuration_definitions(ignore_private=True)
# for base and all, we include galaxy servers
config_entries['GALAXY_SERVERS'] = {}
for server in self._galaxy_servers:
config_entries['GALAXY_SERVERS'][server] = self.config.get_configuration_definitions('galaxy_server', server)
if context.CLIARGS['type'] != 'base':
config_entries['PLUGINS'] = {}
if context.CLIARGS['type'] == 'all':
# now each plugin type
for ptype in C.CONFIGURABLE_PLUGINS:
config_entries['PLUGINS'][ptype.upper()] = self._list_plugin_settings(ptype)
elif context.CLIARGS['type'] != 'base':
# only for requested types
config_entries['PLUGINS'][context.CLIARGS['type']] = self._list_plugin_settings(context.CLIARGS['type'], context.CLIARGS['args'])
return config_entries
def execute_list(self):
"""
list and output available configs
"""
config_entries = self._list_entries_from_args()
if context.CLIARGS['format'] == 'yaml':
output = yaml_dump(config_entries)
elif context.CLIARGS['format'] == 'json':
output = _json.json_dumps_formatted(config_entries)
self.pager(to_text(output, errors='surrogate_or_strict'))
def _get_settings_vars(self, settings, subkey):
data = []
if context.CLIARGS['commented']:
prefix = '#'
else:
prefix = ''
for setting in settings:
if not settings[setting].get('description'):
continue
default = self.config.template_default(settings[setting].get('default', ''), get_constants())
if subkey == 'env':
stype = settings[setting].get('type', '')
if stype == 'boolean':
if default:
default = '1'
else:
default = '0'
elif default:
if stype == 'list':
if not isinstance(default, string_types):
# python lists are not valid env ones
try:
default = ', '.join(default)
except Exception as e:
# list of other stuff
default = '%s' % to_native(default)
if isinstance(default, string_types) and not is_quoted(default):
default = shlex.quote(default)
elif default is None:
default = ''
if subkey in settings[setting] and settings[setting][subkey]:
entry = settings[setting][subkey][-1]['name']
if isinstance(settings[setting]['description'], string_types):
desc = settings[setting]['description']
else:
desc = '\n#'.join(settings[setting]['description'])
name = settings[setting].get('name', setting)
data.append('# %s(%s): %s' % (name, settings[setting].get('type', 'string'), desc))
# TODO: might need quoting and value coercion depending on type
if subkey == 'env':
if entry.startswith('_ANSIBLE_'):
continue
data.append('%s%s=%s' % (prefix, entry, default))
elif subkey == 'vars':
if entry.startswith('_ansible_'):
continue
data.append(prefix + '%s: %s' % (entry, to_text(yaml_short(default), errors='surrogate_or_strict')))
data.append('')
return data
def _get_settings_ini(self, settings, seen):
sections = {}
for o in sorted(settings.keys()):
opt = settings[o]
if not isinstance(opt, Mapping):
# recursed into one of the few settings that is a mapping, now hitting it's strings
continue
if not opt.get('description'):
# its a plugin
new_sections = self._get_settings_ini(opt, seen)
for s in new_sections:
if s in sections:
sections[s].extend(new_sections[s])
else:
sections[s] = new_sections[s]
continue
if isinstance(opt['description'], string_types):
desc = '# (%s) %s' % (opt.get('type', 'string'), opt['description'])
else:
desc = "# (%s) " % opt.get('type', 'string')
desc += "\n# ".join(opt['description'])
if 'ini' in opt and opt['ini']:
entry = opt['ini'][-1]
if entry['section'] not in seen:
seen[entry['section']] = []
if entry['section'] not in sections:
sections[entry['section']] = []
# avoid dupes
if entry['key'] not in seen[entry['section']]:
seen[entry['section']].append(entry['key'])
default = self.config.template_default(opt.get('default', ''), get_constants())
if opt.get('type', '') == 'list' and not isinstance(default, string_types):
# python lists are not valid ini ones
default = ', '.join(default)
elif default is None:
default = ''
if context.CLIARGS.get('commented', False):
entry['key'] = ';%s' % entry['key']
key = desc + '\n%s=%s' % (entry['key'], default)
sections[entry['section']].append(key)
return sections
def execute_init(self):
"""Create initial configuration"""
seen = {}
data = []
config_entries = self._list_entries_from_args()
plugin_types = config_entries.pop('PLUGINS', None)
if context.CLIARGS['format'] == 'ini':
sections = self._get_settings_ini(config_entries, seen)
if plugin_types:
for ptype in plugin_types:
plugin_sections = self._get_settings_ini(plugin_types[ptype], seen)
for s in plugin_sections:
if s in sections:
sections[s].extend(plugin_sections[s])
else:
sections[s] = plugin_sections[s]
if sections:
for section in sections.keys():
data.append('[%s]' % section)
for key in sections[section]:
data.append(key)
data.append('')
data.append('')
elif context.CLIARGS['format'] in ('env', 'vars'): # TODO: add yaml once that config option is added
data = self._get_settings_vars(config_entries, context.CLIARGS['format'])
if plugin_types:
for ptype in plugin_types:
for plugin in plugin_types[ptype].keys():
data.extend(self._get_settings_vars(plugin_types[ptype][plugin], context.CLIARGS['format']))
self.pager(to_text('\n'.join(data), errors='surrogate_or_strict'))
def _render_settings(self, config):
entries = []
for setting in sorted(config):
changed = (config[setting]['origin'] not in ('default', 'REQUIRED') and setting not in _IGNORE_CHANGED)
if context.CLIARGS['format'] == 'display':
if isinstance(config[setting], dict):
# proceed normally
value = config[setting]['value']
if config[setting]['origin'] == 'default' or setting in _IGNORE_CHANGED:
color = 'green'
value = self.config.template_default(value, get_constants())
elif config[setting]['origin'] == 'REQUIRED':
# should include '_terms', '_input', etc
color = 'red'
else:
color = 'yellow'
msg = "%s(%s) = %s" % (setting, config[setting]['origin'], value)
else:
color = 'green'
msg = "%s(%s) = %s" % (setting, 'default', config[setting].get('default'))
entry = stringc(msg, color)
else:
entry = {}
for key in config[setting].keys():
if key == 'type':
continue
entry[key] = config[setting][key]
if not context.CLIARGS['only_changed'] or changed:
entries.append(entry)
return entries
def _get_global_configs(self):
# Add base
config = self.config.get_configuration_definitions(ignore_private=True)
# convert to settings
settings = {}
for setting in config.keys():
v, o = C.config.get_config_value_and_origin(setting, cfile=self.config_file, variables=get_constants())
settings[setting] = {
'name': setting,
'value': v,
'origin': o,
'type': None
}
return self._render_settings(settings)
def _get_plugin_configs(self, ptype, plugins):
# prep loading
loader = getattr(plugin_loader, '%s_loader' % ptype)
# accumulators
output = []
config_entries = {}
# build list
if plugins:
plugin_cs = []
for plugin in plugins:
p = loader.get(plugin, class_only=True)
if p is None:
display.warning("Skipping %s as we could not find matching plugin" % plugin)
else:
plugin_cs.append(loader.get(plugin, class_only=True))
else:
plugin_cs = loader.all(class_only=True)
for plugin in plugin_cs:
# in case of deprecation they diverge
finalname = name = plugin._load_name
if name.startswith('_'):
if os.path.islink(plugin._original_path):
# skip alias
continue
# deprecated, but use 'nice name'
finalname = name.replace('_', '', 1) + ' (DEPRECATED)'
# default entries per plugin
config_entries[finalname] = self.config.get_configuration_definitions(ptype, name)
try:
# populate config entries by loading plugin
dump = loader.get(name, class_only=True)
except Exception as e:
display.warning('Skipping "%s" %s plugin, as we cannot load plugin to check config due to : %s' % (name, ptype, to_native(e)))
continue
# actually get the values
for setting in config_entries[finalname].keys():
try:
v, o = C.config.get_config_value_and_origin(setting, cfile=self.config_file, plugin_type=ptype, plugin_name=name, variables=get_constants())
except AnsibleRequiredOptionError:
v = None
o = 'REQUIRED'
if v is None and o is None:
# not all cases will be error
o = 'REQUIRED'
config_entries[finalname][setting] = {
'name': setting,
'value': v,
'origin': o,
'type': None
}
# pretty please!
results = self._render_settings(config_entries[finalname])
if results:
if context.CLIARGS['format'] == 'display':
# avoid header for empty lists (only changed!)
output.append('\n%s:\n%s' % (finalname, '_' * len(finalname)))
output.extend(results)
else:
output.append({finalname: results})
return output
def _get_galaxy_server_configs(self):
output = []
# add galaxy servers
for server in self._galaxy_servers:
server_config = {}
s_config = self.config.get_configuration_definitions('galaxy_server', server)
for setting in s_config.keys():
try:
v, o = C.config.get_config_value_and_origin(setting, plugin_type='galaxy_server', plugin_name=server, cfile=self.config_file)
except AnsibleError as e:
if s_config[setting].get('required', False):
v = None
o = 'REQUIRED'
else:
raise e
if v is None and o is None:
# not all cases will be error
o = 'REQUIRED'
server_config[setting] = {
'name': setting,
'value': v,
'origin': o,
'type': None
}
if context.CLIARGS['format'] == 'display':
if not context.CLIARGS['only_changed'] or server_config:
equals = '=' * len(server)
output.append(f'\n{server}\n{equals}')
output.extend(self._render_settings(server_config))
else:
output.append({server: server_config})
return output
def execute_dump(self):
"""
Shows the current settings, merges ansible.cfg if specified
"""
output = []
if context.CLIARGS['type'] in ('base', 'all'):
# deal with base
output = self._get_global_configs()
# add galaxy servers
server_config_list = self._get_galaxy_server_configs()
if context.CLIARGS['format'] == 'display':
output.append('\nGALAXY_SERVERS:\n')
output.extend(server_config_list)
else:
configs = {}
for server_config in server_config_list:
server = list(server_config.keys())[0]
server_reduced_config = server_config.pop(server)
configs[server] = list(server_reduced_config.values())
output.append({'GALAXY_SERVERS': configs})
if context.CLIARGS['type'] == 'all':
# add all plugins
for ptype in C.CONFIGURABLE_PLUGINS:
plugin_list = self._get_plugin_configs(ptype, context.CLIARGS['args'])
if context.CLIARGS['format'] == 'display':
if not context.CLIARGS['only_changed'] or plugin_list:
output.append('\n%s:\n%s' % (ptype.upper(), '=' * len(ptype)))
output.extend(plugin_list)
else:
if ptype in ('modules', 'doc_fragments'):
pname = ptype.upper()
else:
pname = '%s_PLUGINS' % ptype.upper()
output.append({pname: plugin_list})
elif context.CLIARGS['type'] != 'base':
# deal with specific plugin
output = self._get_plugin_configs(context.CLIARGS['type'], context.CLIARGS['args'])
if context.CLIARGS['format'] == 'display':
text = '\n'.join(output)
if context.CLIARGS['format'] == 'yaml':
text = yaml_dump(output)
elif context.CLIARGS['format'] == 'json':
text = _json.json_dumps_formatted(output)
self.pager(to_text(text, errors='surrogate_or_strict'))
def execute_validate(self):
found = False
config_entries = self._list_entries_from_args()
plugin_types = config_entries.pop('PLUGINS', None)
galaxy_servers = config_entries.pop('GALAXY_SERVERS', None)
if context.CLIARGS['format'] == 'ini':
if C.CONFIG_FILE is not None:
# validate ini config since it is found
sections = _get_ini_entries(config_entries)
# Also from plugins
if plugin_types:
for ptype in plugin_types:
for plugin in plugin_types[ptype].keys():
plugin_sections = _get_ini_entries(plugin_types[ptype][plugin])
for s in plugin_sections:
if s in sections:
sections[s].update(plugin_sections[s])
else:
sections[s] = plugin_sections[s]
if galaxy_servers:
for server in galaxy_servers:
server_sections = _get_ini_entries(galaxy_servers[server])
for s in server_sections:
if s in sections:
sections[s].update(server_sections[s])
else:
sections[s] = server_sections[s]
if sections:
p = C.config._parsers[C.CONFIG_FILE]
for s in p.sections():
# check for valid sections
if s not in sections:
display.error(f"Found unknown section '{s}' in '{C.CONFIG_FILE}.")
found = True
continue
# check keys in valid sections
for k in p.options(s):
if k not in sections[s]:
display.error(f"Found unknown key '{k}' in section '{s}' in '{C.CONFIG_FILE}.")
found = True
elif context.CLIARGS['format'] == 'env':
# validate any 'ANSIBLE_' env vars found
evars = [varname for varname in os.environ.keys() if _ansible_env_vars(varname)]
if evars:
data = _get_evar_list(config_entries)
if plugin_types:
for ptype in plugin_types:
for plugin in plugin_types[ptype].keys():
data.extend(_get_evar_list(plugin_types[ptype][plugin]))
for evar in evars:
if evar not in data:
display.error(f"Found unknown environment variable '{evar}'.")
found = True
# we found discrepancies!
if found:
sys.exit(1)
# allsgood
display.display("All configurations seem valid!")
def main(args=None):
ConfigCLI.cli_executor(args)
if __name__ == '__main__':
main()
ansible_core-2.19.0b4/lib/ansible/cli/console.py 0000755 0000000 0000000 00000052772 15010426755 020207 0 ustar 00root root #!/usr/bin/env python
# Copyright: (c) 2014, Nandor Sivok
# Copyright: (c) 2016, Redhat Inc
# Copyright: (c) 2018, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# PYTHON_ARGCOMPLETE_OK
from __future__ import annotations
# ansible.cli needs to be imported first, to ensure the source bin/* scripts run that code first
from ansible.cli import CLI
import atexit
import cmd
import getpass
import readline
import os
import sys
from ansible import constants as C
from ansible import context
from ansible.cli.arguments import option_helpers as opt_help
from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.module_utils.common.text.converters import to_native, to_text
from ansible.module_utils.parsing.convert_bool import boolean
from ansible.parsing.splitter import parse_kv
from ansible.playbook.play import Play
from ansible.plugins.list import list_plugins
from ansible.plugins.loader import module_loader, fragment_loader
from ansible.utils import plugin_docs
from ansible.utils.color import stringc
from ansible._internal._datatag._tags import TrustedAsTemplate
from ansible.utils.display import Display
display = Display()
class ConsoleCLI(CLI, cmd.Cmd):
"""
A REPL that allows for running ad-hoc tasks against a chosen inventory
from a nice shell with built-in tab completion (based on dominis'
``ansible-shell``).
It supports several commands, and you can modify its configuration at
runtime:
- ``cd [pattern]``: change host/group
(you can use host patterns eg.: ``app*.dc*:!app01*``)
- ``list``: list available hosts in the current path
- ``list groups``: list groups included in the current path
- ``become``: toggle the become flag
- ``!``: forces shell module instead of the ansible module
(``!yum update -y``)
- ``verbosity [num]``: set the verbosity level
- ``forks [num]``: set the number of forks
- ``become_user [user]``: set the become_user
- ``remote_user [user]``: set the remote_user
- ``become_method [method]``: set the privilege escalation method
- ``check [bool]``: toggle check mode
- ``diff [bool]``: toggle diff mode
- ``timeout [integer]``: set the timeout of tasks in seconds
(0 to disable)
- ``help [command/module]``: display documentation for
the command or module
- ``exit``: exit ``ansible-console``
"""
name = 'ansible-console'
modules = [] # type: list[str] | None
ARGUMENTS = {'host-pattern': 'A name of a group in the inventory, a shell-like glob '
'selecting hosts in inventory or any combination of the two separated by commas.'}
# use specific to console, but fallback to highlight for backwards compatibility
NORMAL_PROMPT = C.COLOR_CONSOLE_PROMPT or C.COLOR_HIGHLIGHT
USES_CONNECTION = True
def __init__(self, args):
super(ConsoleCLI, self).__init__(args)
self.intro = 'Welcome to the ansible console. Type help or ? to list commands.\n'
self.groups = []
self.hosts = []
self.pattern = None
self.variable_manager = None
self.loader = None
self.passwords = dict()
self.cwd = '*'
# Defaults for these are set from the CLI in run()
self.remote_user = None
self.become = None
self.become_user = None
self.become_method = None
self.check_mode = None
self.diff = None
self.forks = None
self.task_timeout = None
self.collections = None
cmd.Cmd.__init__(self)
def init_parser(self):
super(ConsoleCLI, self).init_parser(
desc="REPL console for executing Ansible tasks.",
epilog="This is not a live session/connection: each task is executed in the background and returns its results."
)
opt_help.add_runas_options(self.parser)
opt_help.add_inventory_options(self.parser)
opt_help.add_connect_options(self.parser)
opt_help.add_check_options(self.parser)
opt_help.add_vault_options(self.parser)
opt_help.add_fork_options(self.parser)
opt_help.add_module_options(self.parser)
opt_help.add_basedir_options(self.parser)
opt_help.add_runtask_options(self.parser)
opt_help.add_tasknoplay_options(self.parser)
# options unique to shell
self.parser.add_argument('pattern', help='host pattern', metavar='pattern', default='all', nargs='?')
self.parser.add_argument('--step', dest='step', action='store_true',
help="one-step-at-a-time: confirm each task before running")
def post_process_args(self, options):
options = super(ConsoleCLI, self).post_process_args(options)
display.verbosity = options.verbosity
self.validate_conflicts(options, runas_opts=True, fork_opts=True)
return options
def get_names(self):
return dir(self)
def cmdloop(self):
try:
cmd.Cmd.cmdloop(self)
except KeyboardInterrupt:
self.cmdloop()
except EOFError:
self.display("[Ansible-console was exited]")
self.do_exit(self)
def set_prompt(self):
login_user = self.remote_user or getpass.getuser()
self.selected = self.inventory.list_hosts(self.cwd)
prompt = "%s@%s (%d)[f:%s]" % (login_user, self.cwd, len(self.selected), self.forks)
if self.become and self.become_user in [None, 'root']:
prompt += "# "
color = C.COLOR_ERROR
else:
prompt += "$ "
color = self.NORMAL_PROMPT
self.prompt = stringc(prompt, color, wrap_nonvisible_chars=True)
def list_modules(self):
return list_plugins('module', self.collections)
def default(self, line, forceshell=False):
""" actually runs modules """
if line.startswith("#"):
return False
if not self.cwd:
display.error("No host found")
return False
# defaults
module = 'shell'
module_args = line
if forceshell is not True:
possible_module, *possible_args = line.split()
if module_loader.find_plugin(possible_module):
# we found module!
module = possible_module
if possible_args:
module_args = ' '.join(possible_args)
else:
module_args = ''
module_args = TrustedAsTemplate().tag(module_args)
if self.callback:
cb = self.callback
elif C.DEFAULT_LOAD_CALLBACK_PLUGINS and C.DEFAULT_STDOUT_CALLBACK != 'default':
cb = C.DEFAULT_STDOUT_CALLBACK
else:
cb = 'minimal'
result = None
try:
check_raw = module in C._ACTION_ALLOWS_RAW_ARGS
task = dict(action=dict(module=module, args=parse_kv(module_args, check_raw=check_raw)), timeout=self.task_timeout)
play_ds = dict(
name="Ansible Shell",
hosts=self.cwd,
gather_facts='no',
tasks=[task],
remote_user=self.remote_user,
become=self.become,
become_user=self.become_user,
become_method=self.become_method,
check_mode=self.check_mode,
diff=self.diff,
collections=self.collections,
)
play = Play().load(play_ds, variable_manager=self.variable_manager, loader=self.loader)
except Exception as e:
display.error(u"Unable to build command: %s" % to_text(e))
return False
try:
# now create a task queue manager to execute the play
self._tqm = None
try:
self._tqm = TaskQueueManager(
inventory=self.inventory,
variable_manager=self.variable_manager,
loader=self.loader,
passwords=self.passwords,
stdout_callback=cb,
run_additional_callbacks=C.DEFAULT_LOAD_CALLBACK_PLUGINS,
run_tree=False,
forks=self.forks,
)
result = self._tqm.run(play)
display.debug(result)
finally:
if self._tqm:
self._tqm.cleanup()
if self.loader:
self.loader.cleanup_all_tmp_files()
if result is None:
display.error("No hosts found")
return False
except KeyboardInterrupt:
display.error('User interrupted execution')
return False
except Exception as ex:
display.error(ex)
return False
def emptyline(self):
return
def do_shell(self, arg):
"""
You can run shell commands through the shell module.
eg.:
shell ps uax | grep java | wc -l
shell killall python
shell halt -n
You can use the ! to force the shell module. eg.:
!ps aux | grep java | wc -l
"""
self.default(arg, True)
def help_shell(self):
display.display("You can run shell commands through the shell module.")
def do_forks(self, arg):
"""Set the number of forks"""
if arg:
try:
forks = int(arg)
except TypeError:
display.error('Invalid argument for "forks"')
self.usage_forks()
if forks > 0:
self.forks = forks
self.set_prompt()
else:
display.display('forks must be greater than or equal to 1')
else:
self.usage_forks()
def help_forks(self):
display.display("Set the number of forks to use per task")
self.usage_forks()
def usage_forks(self):
display.display('Usage: forks ')
do_serial = do_forks
help_serial = help_forks
def do_collections(self, arg):
"""Set list of collections for 'short name' usage"""
if arg in ('', 'none'):
self.collections = None
elif not arg:
self.usage_collections()
else:
collections = arg.split(',')
for collection in collections:
if self.collections is None:
self.collections = []
self.collections.append(collection.strip())
if self.collections:
display.v('Collections name search is set to: %s' % ', '.join(self.collections))
else:
display.v('Collections name search is using defaults')
def help_collections(self):
display.display("Set the collection name search path when using short names for plugins")
self.usage_collections()
def usage_collections(self):
display.display('Usage: collections [, ...]\n Use empty quotes or "none" to reset to default.\n')
def do_verbosity(self, arg):
"""Set verbosity level"""
if not arg:
display.display('Usage: verbosity ')
else:
try:
display.verbosity = int(arg)
display.v('verbosity level set to %s' % arg)
except (TypeError, ValueError) as e:
display.error('The verbosity must be a valid integer: %s' % to_text(e))
def help_verbosity(self):
display.display("Set the verbosity level, equivalent to -v for 1 and -vvvv for 4.")
def do_cd(self, arg):
"""
Change active host/group. You can use hosts patterns as well eg.:
cd webservers
cd webservers:dbservers
cd webservers:!phoenix
cd webservers:&staging
cd webservers:dbservers:&staging:!phoenix
"""
if not arg:
self.cwd = '*'
elif arg in '/*':
self.cwd = 'all'
elif self.inventory.get_hosts(arg):
self.cwd = arg
else:
display.display("no host matched")
self.set_prompt()
def help_cd(self):
display.display("Change active host/group. ")
self.usage_cd()
def usage_cd(self):
display.display("Usage: cd ||")
def do_list(self, arg):
"""List the hosts in the current group"""
if not arg:
for host in self.selected:
display.display(host.name)
elif arg == 'groups':
for group in self.groups:
display.display(group)
else:
display.error('Invalid option passed to "list"')
self.help_list()
def help_list(self):
display.display("List the hosts in the current group or a list of groups if you add 'groups'.")
def do_become(self, arg):
"""Toggle whether plays run with become"""
if arg:
self.become = boolean(arg, strict=False)
display.v("become changed to %s" % self.become)
self.set_prompt()
else:
display.display("Please specify become value, e.g. `become yes`")
def help_become(self):
display.display("Toggle whether the tasks are run with become")
def do_remote_user(self, arg):
"""Given a username, set the remote user plays are run by"""
if arg:
self.remote_user = arg
self.set_prompt()
else:
display.display("Please specify a remote user, e.g. `remote_user root`")
def help_remote_user(self):
display.display("Set the user for use as login to the remote target")
def do_become_user(self, arg):
"""Given a username, set the user that plays are run by when using become"""
if arg:
self.become_user = arg
else:
display.display("Please specify a user, e.g. `become_user jenkins`")
display.v("Current user is %s" % self.become_user)
self.set_prompt()
def help_become_user(self):
display.display("Set the user for use with privilege escalation (which remote user attempts to 'become' when become is enabled)")
def do_become_method(self, arg):
"""Given a become_method, set the privilege escalation method when using become"""
if arg:
self.become_method = arg
display.v("become_method changed to %s" % self.become_method)
else:
display.display("Please specify a become_method, e.g. `become_method su`")
display.v("Current become_method is %s" % self.become_method)
def help_become_method(self):
display.display("Set the privilege escalation plugin to use when become is enabled")
def do_check(self, arg):
"""Toggle whether plays run with check mode"""
if arg:
self.check_mode = boolean(arg, strict=False)
display.display("check mode changed to %s" % self.check_mode)
else:
display.display("Please specify check mode value, e.g. `check yes`")
display.v("check mode is currently %s." % self.check_mode)
def help_check(self):
display.display("Toggle check_mode for the tasks")
def do_diff(self, arg):
"""Toggle whether plays run with diff"""
if arg:
self.diff = boolean(arg, strict=False)
display.display("diff mode changed to %s" % self.diff)
else:
display.display("Please specify a diff value , e.g. `diff yes`")
display.v("diff mode is currently %s" % self.diff)
def help_diff(self):
display.display("Toggle diff output for the tasks")
def do_timeout(self, arg):
"""Set the timeout"""
if arg:
try:
timeout = int(arg)
if timeout < 0:
display.error('The timeout must be greater than or equal to 1, use 0 to disable')
else:
self.task_timeout = timeout
except (TypeError, ValueError) as e:
display.error('The timeout must be a valid positive integer, or 0 to disable: %s' % to_text(e))
else:
self.usage_timeout()
def help_timeout(self):
display.display("Set task timeout in seconds")
self.usage_timeout()
def usage_timeout(self):
display.display('Usage: timeout ')
def do_exit(self, args):
"""Exits from the console"""
sys.stdout.write('\nAnsible-console was exited.\n')
return -1
def help_exit(self):
display.display("LEAVE!")
do_EOF = do_exit
help_EOF = help_exit
def helpdefault(self, module_name):
if module_name:
in_path = module_loader.find_plugin(module_name)
if in_path:
oc, a, _dummy1, _dummy2 = plugin_docs.get_docstring(in_path, fragment_loader)
if oc:
display.display(oc['short_description'])
display.display('Parameters:')
for opt in oc['options'].keys():
display.display(' ' + stringc(opt, self.NORMAL_PROMPT) + ' ' + oc['options'][opt]['description'][0])
else:
display.error('No documentation found for %s.' % module_name)
else:
display.error('%s is not a valid command, use ? to list all valid commands.' % module_name)
def help_help(self):
display.warning("Don't be redundant!")
def complete_cd(self, text, line, begidx, endidx):
mline = line.partition(' ')[2]
offs = len(mline) - len(text)
if self.cwd in ('all', '*', '\\'):
completions = self.hosts + self.groups
else:
completions = [x.name for x in self.inventory.list_hosts(self.cwd)]
return [to_native(s)[offs:] for s in completions if to_native(s).startswith(to_native(mline))]
def completedefault(self, text, line, begidx, endidx):
if line.split()[0] in self.list_modules():
mline = line.split(' ')[-1]
offs = len(mline) - len(text)
completions = self.module_args(line.split()[0])
return [s[offs:] + '=' for s in completions if s.startswith(mline)]
def module_args(self, module_name):
in_path = module_loader.find_plugin(module_name)
oc, a, _dummy1, _dummy2 = plugin_docs.get_docstring(in_path, fragment_loader, is_module=True)
return list(oc['options'].keys())
def run(self):
super(ConsoleCLI, self).run()
sshpass = None
becomepass = None
# hosts
self.pattern = context.CLIARGS['pattern']
self.cwd = self.pattern
# Defaults from the command line
self.remote_user = context.CLIARGS['remote_user']
self.become = context.CLIARGS['become']
self.become_user = context.CLIARGS['become_user']
self.become_method = context.CLIARGS['become_method']
self.check_mode = context.CLIARGS['check']
self.diff = context.CLIARGS['diff']
self.forks = context.CLIARGS['forks']
self.task_timeout = context.CLIARGS['task_timeout']
# set module path if needed
if context.CLIARGS['module_path']:
for path in context.CLIARGS['module_path']:
if path:
module_loader.add_directory(path)
# dynamically add 'canonical' modules as commands, aliases could be used and dynamically loaded
self.modules = self.list_modules()
for module in self.modules:
setattr(self, 'do_' + module, lambda arg, module=module: self.default(module + ' ' + arg))
setattr(self, 'help_' + module, lambda module=module: self.helpdefault(module))
(sshpass, becomepass) = self.ask_passwords()
self.passwords = {'conn_pass': sshpass, 'become_pass': becomepass}
self.loader, self.inventory, self.variable_manager = self._play_prereqs()
hosts = self.get_host_list(self.inventory, context.CLIARGS['subset'], self.pattern)
self.groups = self.inventory.list_groups()
self.hosts = [x.name for x in hosts]
# This hack is to work around readline issues on a mac:
# http://stackoverflow.com/a/7116997/541202
if 'libedit' in readline.__doc__:
readline.parse_and_bind("bind ^I rl_complete")
else:
readline.parse_and_bind("tab: complete")
histfile = os.path.join(os.path.expanduser("~"), ".ansible-console_history")
try:
readline.read_history_file(histfile)
except IOError:
pass
atexit.register(readline.write_history_file, histfile)
self.set_prompt()
self.cmdloop()
def __getattr__(self, name):
""" handle not found to populate dynamically a module function if module matching name exists """
attr = None
if name.startswith('do_'):
module = name.replace('do_', '')
if module_loader.find_plugin(module):
setattr(self, name, lambda arg, module=module: self.default(module + ' ' + arg))
attr = object.__getattr__(self, name)
elif name.startswith('help_'):
module = name.replace('help_', '')
if module_loader.find_plugin(module):
setattr(self, name, lambda module=module: self.helpdefault(module))
attr = object.__getattr__(self, name)
if attr is None:
raise AttributeError(f"{self.__class__} does not have a {name} attribute")
return attr
def main(args=None):
ConsoleCLI.cli_executor(args)
if __name__ == '__main__':
main()
ansible_core-2.19.0b4/lib/ansible/cli/doc.py 0000755 0000000 0000000 00000211762 15010426755 017306 0 ustar 00root root #!/usr/bin/env python
# Copyright: (c) 2014, James Tanner
# Copyright: (c) 2018, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# PYTHON_ARGCOMPLETE_OK
from __future__ import annotations
# ansible.cli needs to be imported first, to ensure the source bin/* scripts run that code first
from ansible.cli import CLI
import importlib
import pkgutil
import os
import os.path
import re
import textwrap
import yaml
import ansible.plugins.loader as plugin_loader
from pathlib import Path
from ansible import constants as C
from ansible import context
from ansible.cli.arguments import option_helpers as opt_help
from ansible.collections.list import list_collection_dirs
from ansible.errors import AnsibleError, AnsibleOptionsError, AnsibleParserError, AnsiblePluginNotFound
from ansible.module_utils.common.text.converters import to_native, to_text
from ansible.module_utils.common.collections import is_sequence
from ansible.module_utils.common.yaml import yaml_dump
from ansible.module_utils.six import string_types
from ansible.parsing.plugin_docs import read_docstub
from ansible.parsing.yaml.dumper import AnsibleDumper
from ansible.parsing.yaml.loader import AnsibleLoader
from ansible._internal._yaml._loader import AnsibleInstrumentedLoader
from ansible.plugins.list import list_plugins
from ansible.plugins.loader import action_loader, fragment_loader
from ansible.utils.collection_loader import AnsibleCollectionConfig, AnsibleCollectionRef
from ansible.utils.collection_loader._collection_finder import _get_collection_name_from_path
from ansible.utils.color import stringc
from ansible.utils.display import Display
from ansible.utils.plugin_docs import get_plugin_docs, get_docstring, get_versioned_doclink
from ansible.template import trust_as_template
from ansible._internal import _json
display = Display()
TARGET_OPTIONS = C.DOCUMENTABLE_PLUGINS + ('role', 'keyword',)
PB_OBJECTS = ['Play', 'Role', 'Block', 'Task', 'Handler']
PB_LOADED = {}
SNIPPETS = ['inventory', 'lookup', 'module']
# hardcoded from ascii values
STYLE = {
'BLINK': '\033[5m',
'BOLD': '\033[1m',
'HIDE': '\033[8m',
# 'NORMAL': '\x01b[0m', # newer?
'NORMAL': '\033[0m',
'RESET': "\033[0;0m",
# 'REVERSE':"\033[;7m", # newer?
'REVERSE': "\033[7m",
'UNDERLINE': '\033[4m',
}
# previously existing string identifiers
NOCOLOR = {
'BOLD': r'*%s*',
'UNDERLINE': r'`%s`',
'MODULE': r'[%s]',
'PLUGIN': r'[%s]',
}
ref_style = {
'MODULE': C.COLOR_DOC_MODULE,
'REF': C.COLOR_DOC_REFERENCE,
'LINK': C.COLOR_DOC_LINK,
'DEP': C.COLOR_DOC_DEPRECATED,
'CONSTANT': C.COLOR_DOC_CONSTANT,
'PLUGIN': C.COLOR_DOC_PLUGIN,
}
def jdump(text):
try:
display.display(_json.json_dumps_formatted(text))
except TypeError as ex:
raise AnsibleError('We could not convert all the documentation into JSON as there was a conversion issue.') from ex
class RoleMixin(object):
"""A mixin containing all methods relevant to role argument specification functionality.
Note: The methods for actual display of role data are not present here.
"""
# Potential locations of the role arg spec file in the meta subdir, with main.yml
# having the lowest priority.
ROLE_METADATA_FILES = ["main" + e for e in C.YAML_FILENAME_EXTENSIONS]
ROLE_ARGSPEC_FILES = ['argument_specs' + e for e in C.YAML_FILENAME_EXTENSIONS] + ROLE_METADATA_FILES
def _load_role_data(self, root, files, role_name, collection):
""" Load and process the YAML for the first found of a set of role files
:param str root: The root path to get the files from
:param list files: List of candidate file names in order of precedence
:param str role_name: The name of the role for which we want the argspec data.
:param str collection: collection name or None in case of stand alone roles
:returns: A dict that contains the data requested, empty if no data found
"""
if collection:
meta_path = os.path.join(root, 'roles', role_name, 'meta')
else:
meta_path = os.path.join(root, 'meta')
# Check all potential spec files
path = None
for specfile in files:
full_path = os.path.join(meta_path, specfile)
if os.path.exists(full_path):
path = full_path
break
if path is None:
return {}
try:
with open(path, 'r') as f:
data = yaml.load(trust_as_template(f), Loader=AnsibleLoader)
if data is None:
data = {}
except (IOError, OSError) as ex:
raise AnsibleParserError(f"Could not read the role {role_name!r} (at {path}).") from ex
return data
def _load_metadata(self, role_name, role_path, collection):
"""Load the roles metadata from the source file.
:param str role_name: The name of the role for which we want the argspec data.
:param str role_path: Path to the role/collection root.
:param str collection: collection name or None in case of stand alone roles
:returns: A dict of all role meta data, except ``argument_specs`` or an empty dict
"""
data = self._load_role_data(role_path, self.ROLE_METADATA_FILES, role_name, collection)
del data['argument_specs']
return data
def _load_argspec(self, role_name, role_path, collection):
"""Load the role argument spec data from the source file.
:param str role_name: The name of the role for which we want the argspec data.
:param str role_path: Path to the role/collection root.
:param str collection: collection name or None in case of stand alone roles
We support two files containing the role arg spec data: either meta/main.yml
or meta/argument_spec.yml. The argument_spec.yml file will take precedence
over the meta/main.yml file, if it exists. Data is NOT combined between the
two files.
:returns: A dict of all data underneath the ``argument_specs`` top-level YAML
key in the argspec data file. Empty dict is returned if there is no data.
"""
try:
data = self._load_role_data(role_path, self.ROLE_ARGSPEC_FILES, role_name, collection)
data = data.get('argument_specs', {})
except Exception as e:
# we keep error info, but let caller deal with it
data = {'error': 'Failed to process role (%s): %s' % (role_name, to_native(e)), 'exception': e}
return data
def _find_all_normal_roles(self, role_paths, name_filters=None):
"""Find all non-collection roles that have an argument spec file.
Note that argument specs do not actually need to exist within the spec file.
:param role_paths: A tuple of one or more role paths. When a role with the same name
is found in multiple paths, only the first-found role is returned.
:param name_filters: A tuple of one or more role names used to filter the results.
:returns: A set of tuples consisting of: role name, full role path
"""
found = set()
found_names = set()
for path in role_paths:
if not os.path.isdir(path):
continue
# Check each subdir for an argument spec file
for entry in os.listdir(path):
role_path = os.path.join(path, entry)
# Check all potential spec files
for specfile in self.ROLE_ARGSPEC_FILES:
full_path = os.path.join(role_path, 'meta', specfile)
if os.path.exists(full_path):
if name_filters is None or entry in name_filters:
# select first-found role
if entry not in found_names:
found_names.add(entry)
# None here stands for 'colleciton', which stand alone roles dont have
# makes downstream code simpler by having same structure as collection roles
found.add((entry, None, role_path))
# only read first existing spec
break
return found
def _find_all_collection_roles(self, name_filters=None, collection_filter=None):
"""Find all collection roles with an argument spec file.
Note that argument specs do not actually need to exist within the spec file.
:param name_filters: A tuple of one or more role names used to filter the results. These
might be fully qualified with the collection name (e.g., community.general.roleA)
or not (e.g., roleA).
:param collection_filter: A list of strings containing the FQCN of a collection which will
be used to limit results. This filter will take precedence over the name_filters.
:returns: A set of tuples consisting of: role name, collection name, collection path
"""
found = set()
b_colldirs = list_collection_dirs(coll_filter=collection_filter)
for b_path in b_colldirs:
path = to_text(b_path, errors='surrogate_or_strict')
collname = _get_collection_name_from_path(b_path)
roles_dir = os.path.join(path, 'roles')
if os.path.exists(roles_dir):
for entry in os.listdir(roles_dir):
# Check all potential spec files
for specfile in self.ROLE_ARGSPEC_FILES:
full_path = os.path.join(roles_dir, entry, 'meta', specfile)
if os.path.exists(full_path):
if name_filters is None:
found.add((entry, collname, path))
else:
# Name filters might contain a collection FQCN or not.
for fqcn in name_filters:
if len(fqcn.split('.')) == 3:
(ns, col, role) = fqcn.split('.')
if '.'.join([ns, col]) == collname and entry == role:
found.add((entry, collname, path))
elif fqcn == entry:
found.add((entry, collname, path))
break
return found
def _build_summary(self, role, collection, meta, argspec):
"""Build a summary dict for a role.
Returns a simplified role arg spec containing only the role entry points and their
short descriptions, and the role collection name (if applicable).
:param role: The simple role name.
:param collection: The collection containing the role (None or empty string if N/A).
:param meta: dictionary with galaxy information (None or empty string if N/A).
:param argspec: The complete role argspec data dict.
:returns: A tuple with the FQCN role name and a summary dict.
"""
if meta and meta.get('galaxy_info'):
summary = meta['galaxy_info']
else:
summary = {'description': 'UNDOCUMENTED'}
summary['entry_points'] = {}
if collection:
fqcn = '.'.join([collection, role])
summary['collection'] = collection
else:
fqcn = role
for ep in argspec.keys():
entry_spec = argspec[ep] or {}
summary['entry_points'][ep] = entry_spec.get('short_description', '')
return (fqcn, summary)
def _build_doc(self, role, path, collection, argspec, entry_point):
if collection:
fqcn = '.'.join([collection, role])
else:
fqcn = role
doc = {}
doc['path'] = path
doc['collection'] = collection
if 'error' in argspec:
doc.update(argspec)
else:
doc['entry_points'] = {}
for ep in argspec.keys():
if entry_point is None or ep == entry_point:
entry_spec = argspec[ep] or {}
doc['entry_points'][ep] = entry_spec
# If we didn't add any entry points (b/c of filtering), ignore this entry.
if len(doc['entry_points'].keys()) == 0:
doc = None
return (fqcn, doc)
def _create_role_list(self, fail_on_errors=True):
"""Return a dict describing the listing of all roles with arg specs.
:param role_paths: A tuple of one or more role paths.
:returns: A dict indexed by role name, with 'collection' and 'entry_points' keys per role.
Example return:
results = {
'roleA': {
'collection': '',
'entry_points': {
'main': 'Short description for main'
}
},
'a.b.c.roleB': {
'collection': 'a.b.c',
'entry_points': {
'main': 'Short description for main',
'alternate': 'Short description for alternate entry point'
}
'x.y.z.roleB': {
'collection': 'x.y.z',
'entry_points': {
'main': 'Short description for main',
}
},
}
"""
roles_path = self._get_roles_path()
collection_filter = self._get_collection_filter()
if not collection_filter:
roles = self._find_all_normal_roles(roles_path)
else:
roles = set()
collroles = self._find_all_collection_roles(collection_filter=collection_filter)
result = {}
for role, collection, role_path in (roles | collroles):
try:
meta = self._load_metadata(role, role_path, collection)
except Exception as e:
display.vvv('No metadata for role (%s) due to: %s' % (role, to_native(e)), True)
meta = {}
argspec = self._load_argspec(role, role_path, collection)
if 'error' in argspec:
if fail_on_errors:
raise argspec['exception']
else:
display.warning('Skipping role (%s) due to: %s' % (role, argspec['error']), True)
continue
fqcn, summary = self._build_summary(role, collection, meta, argspec)
result[fqcn] = summary
return result
def _create_role_doc(self, role_names, entry_point=None, fail_on_errors=True):
"""
:param role_names: A tuple of one or more role names.
:param role_paths: A tuple of one or more role paths.
:param entry_point: A role entry point name for filtering.
:param fail_on_errors: When set to False, include errors in the JSON output instead of raising errors
:returns: A dict indexed by role name, with 'collection', 'entry_points', and 'path' keys per role.
"""
roles_path = self._get_roles_path()
roles = self._find_all_normal_roles(roles_path, name_filters=role_names)
collroles = self._find_all_collection_roles(name_filters=role_names)
result = {}
for role, collection, role_path in (roles | collroles):
argspec = self._load_argspec(role, role_path, collection)
if 'error' in argspec:
if fail_on_errors:
raise argspec['exception']
else:
display.warning('Skipping role (%s) due to: %s' % (role, argspec['error']), True)
continue
fqcn, doc = self._build_doc(role, role_path, collection, argspec, entry_point)
if doc:
result[fqcn] = doc
return result
def _doclink(url):
# assume that if it is relative, it is for docsite, ignore rest
if not url.startswith(("http", "..")):
url = get_versioned_doclink(url)
return url
def _format(string, *args):
""" add ascii formatting or delimiters """
for style in args:
if style not in ref_style and style.upper() not in STYLE and style not in C.COLOR_CODES:
raise KeyError("Invalid format value supplied: %s" % style)
if C.ANSIBLE_NOCOLOR:
# ignore most styles, but some already had 'identifier strings'
if style in NOCOLOR:
string = NOCOLOR[style] % string
elif style in C.COLOR_CODES:
string = stringc(string, style)
elif style in ref_style:
# assumes refs are also always colors
string = stringc(string, ref_style[style])
else:
# start specific style and 'end' with normal
string = '%s%s%s' % (STYLE[style.upper()], string, STYLE['NORMAL'])
return string
class DocCLI(CLI, RoleMixin):
""" displays information on modules installed in Ansible libraries.
It displays a terse listing of plugins and their short descriptions,
provides a printout of their DOCUMENTATION strings,
and it can create a short "snippet" which can be pasted into a playbook. """
name = 'ansible-doc'
# default ignore list for detailed views
IGNORE = ('module', 'docuri', 'version_added', 'version_added_collection', 'short_description',
'now_date', 'plainexamples', 'returndocs', 'collection', 'plugin_name')
# Warning: If you add more elements here, you also need to add it to the docsite build (in the
# ansible-community/antsibull repo)
_ITALIC = re.compile(r"\bI\(([^)]+)\)")
_BOLD = re.compile(r"\bB\(([^)]+)\)")
_MODULE = re.compile(r"\bM\(([^)]+)\)")
_PLUGIN = re.compile(r"\bP\(([^#)]+)#([a-z]+)\)")
_LINK = re.compile(r"\bL\(([^)]+), *([^)]+)\)")
_URL = re.compile(r"\bU\(([^)]+)\)")
_REF = re.compile(r"\bR\(([^)]+), *([^)]+)\)")
_CONST = re.compile(r"\bC\(([^)]+)\)")
_SEM_PARAMETER_STRING = r"\(((?:[^\\)]+|\\.)+)\)"
_SEM_OPTION_NAME = re.compile(r"\bO" + _SEM_PARAMETER_STRING)
_SEM_OPTION_VALUE = re.compile(r"\bV" + _SEM_PARAMETER_STRING)
_SEM_ENV_VARIABLE = re.compile(r"\bE" + _SEM_PARAMETER_STRING)
_SEM_RET_VALUE = re.compile(r"\bRV" + _SEM_PARAMETER_STRING)
_RULER = re.compile(r"\bHORIZONTALLINE\b")
# helper for unescaping
_UNESCAPE = re.compile(r"\\(.)")
_FQCN_TYPE_PREFIX_RE = re.compile(r'^([^.]+\.[^.]+\.[^#]+)#([a-z]+):(.*)$')
_IGNORE_MARKER = 'ignore:'
# rst specific
_RST_NOTE = re.compile(r".. note::")
_RST_SEEALSO = re.compile(r".. seealso::")
_RST_ROLES = re.compile(r":\w+?:`")
_RST_DIRECTIVES = re.compile(r".. \w+?::")
def __init__(self, args):
super(DocCLI, self).__init__(args)
self.plugin_list = set()
@staticmethod
def _tty_ify_sem_simle(matcher):
text = DocCLI._UNESCAPE.sub(r'\1', matcher.group(1))
return f"`{text}'"
@staticmethod
def _tty_ify_sem_complex(matcher):
text = DocCLI._UNESCAPE.sub(r'\1', matcher.group(1))
value = None
if '=' in text:
text, value = text.split('=', 1)
m = DocCLI._FQCN_TYPE_PREFIX_RE.match(text)
if m:
plugin_fqcn = m.group(1)
plugin_type = m.group(2)
text = m.group(3)
elif text.startswith(DocCLI._IGNORE_MARKER):
text = text[len(DocCLI._IGNORE_MARKER):]
plugin_fqcn = plugin_type = ''
else:
plugin_fqcn = plugin_type = ''
entrypoint = None
if ':' in text:
entrypoint, text = text.split(':', 1)
if value is not None:
text = f"{text}={value}"
if plugin_fqcn and plugin_type:
plugin_suffix = '' if plugin_type in ('role', 'module', 'playbook') else ' plugin'
plugin = f"{plugin_type}{plugin_suffix} {plugin_fqcn}"
if plugin_type == 'role' and entrypoint is not None:
plugin = f"{plugin}, {entrypoint} entrypoint"
return f"`{text}' (of {plugin})"
return f"`{text}'"
@classmethod
def tty_ify(cls, text):
# general formatting
t = cls._ITALIC.sub(_format(r"\1", 'UNDERLINE'), text) # no ascii code for this
t = cls._BOLD.sub(_format(r"\1", 'BOLD'), t)
t = cls._MODULE.sub(_format(r"\1", 'MODULE'), t) # M(word) => [word]
t = cls._URL.sub(r"\1", t) # U(word) => word
t = cls._LINK.sub(r"\1 <\2>", t) # L(word, url) => word
t = cls._PLUGIN.sub(_format("[" + r"\1" + "]", 'PLUGIN'), t) # P(word#type) => [word]
t = cls._REF.sub(_format(r"\1", 'REF'), t) # R(word, sphinx-ref) => word
t = cls._CONST.sub(_format(r"`\1'", 'CONSTANT'), t)
t = cls._SEM_OPTION_NAME.sub(cls._tty_ify_sem_complex, t) # O(expr)
t = cls._SEM_OPTION_VALUE.sub(cls._tty_ify_sem_simle, t) # V(expr)
t = cls._SEM_ENV_VARIABLE.sub(cls._tty_ify_sem_simle, t) # E(expr)
t = cls._SEM_RET_VALUE.sub(cls._tty_ify_sem_complex, t) # RV(expr)
t = cls._RULER.sub("\n{0}\n".format("-" * 13), t) # HORIZONTALLINE => -------
# remove rst
t = cls._RST_SEEALSO.sub(r"See also:", t) # seealso to See also:
t = cls._RST_NOTE.sub(_format(r"Note:", 'bold'), t) # .. note:: to note:
t = cls._RST_ROLES.sub(r"`", t) # remove :ref: and other tags, keep tilde to match ending one
t = cls._RST_DIRECTIVES.sub(r"", t) # remove .. stuff:: in general
# handle docsite refs
# U(word) => word
t = re.sub(cls._URL, lambda m: _format(r"%s" % _doclink(m.group(1)), 'LINK'), t)
# L(word, url) => word
t = re.sub(cls._LINK, lambda m: r"%s <%s>" % (m.group(1), _format(_doclink(m.group(2)), 'LINK')), t)
return t
def init_parser(self):
coll_filter = 'A supplied argument will be used for filtering, can be a namespace or full collection name.'
super(DocCLI, self).init_parser(
desc="plugin documentation tool",
epilog="See man pages for Ansible CLI options or website for tutorials https://docs.ansible.com"
)
opt_help.add_module_options(self.parser)
opt_help.add_basedir_options(self.parser)
# targets
self.parser.add_argument('args', nargs='*', help='Plugin', metavar='plugin')
self.parser.add_argument("-t", "--type", action="store", default='module', dest='type',
help='Choose which plugin type (defaults to "module"). '
'Available plugin types are : {0}'.format(TARGET_OPTIONS),
choices=TARGET_OPTIONS)
# formatting
self.parser.add_argument("-j", "--json", action="store_true", default=False, dest='json_format',
help='Change output into json format.')
# TODO: warn if not used with -t roles
# role-specific options
self.parser.add_argument("-r", "--roles-path", dest='roles_path', default=C.DEFAULT_ROLES_PATH,
type=opt_help.unfrack_path(pathsep=True),
action=opt_help.PrependListAction,
help='The path to the directory containing your roles.')
# exclusive modifiers
exclusive = self.parser.add_mutually_exclusive_group()
# TODO: warn if not used with -t roles
exclusive.add_argument("-e", "--entry-point", dest="entry_point",
help="Select the entry point for role(s).")
# TODO: warn with --json as it is incompatible
exclusive.add_argument("-s", "--snippet", action="store_true", default=False, dest='show_snippet',
help='Show playbook snippet for these plugin types: %s' % ', '.join(SNIPPETS))
# TODO: warn when arg/plugin is passed
exclusive.add_argument("-F", "--list_files", action="store_true", default=False, dest="list_files",
help='Show plugin names and their source files without summaries (implies --list). %s' % coll_filter)
exclusive.add_argument("-l", "--list", action="store_true", default=False, dest='list_dir',
help='List available plugins. %s' % coll_filter)
exclusive.add_argument("--metadata-dump", action="store_true", default=False, dest='dump',
help='**For internal use only** Dump json metadata for all entries, ignores other options.')
# generic again
self.parser.add_argument("--no-fail-on-errors", action="store_true", default=False, dest='no_fail_on_errors',
help='**For internal use only** Only used for --metadata-dump. '
'Do not fail on errors. Report the error message in the JSON instead.')
def post_process_args(self, options):
options = super(DocCLI, self).post_process_args(options)
display.verbosity = options.verbosity
return options
def display_plugin_list(self, results):
# format for user
displace = max(len(x) for x in results.keys())
linelimit = display.columns - displace - 5
text = []
deprecated = []
# format display per option
if context.CLIARGS['list_files']:
# list plugin file names
for plugin in sorted(results.keys()):
filename = to_native(results[plugin])
# handle deprecated for builtin/legacy
pbreak = plugin.split('.')
if pbreak[-1].startswith('_') and pbreak[0] == 'ansible' and pbreak[1] in ('builtin', 'legacy'):
pbreak[-1] = pbreak[-1][1:]
plugin = '.'.join(pbreak)
deprecated.append("%-*s %-*.*s" % (displace, plugin, linelimit, len(filename), filename))
else:
text.append("%-*s %-*.*s" % (displace, plugin, linelimit, len(filename), filename))
else:
# list plugin names and short desc
for plugin in sorted(results.keys()):
desc = DocCLI.tty_ify(results[plugin])
if len(desc) > linelimit:
desc = desc[:linelimit] + '...'
pbreak = plugin.split('.')
# TODO: add mark for deprecated collection plugins
if pbreak[-1].startswith('_') and plugin.startswith(('ansible.builtin.', 'ansible.legacy.')):
# Handle deprecated ansible.builtin plugins
pbreak[-1] = pbreak[-1][1:]
plugin = '.'.join(pbreak)
deprecated.append("%-*s %-*.*s" % (displace, plugin, linelimit, len(desc), desc))
else:
text.append("%-*s %-*.*s" % (displace, plugin, linelimit, len(desc), desc))
if len(deprecated) > 0:
text.append("\nDEPRECATED:")
text.extend(deprecated)
# display results
DocCLI.pager("\n".join(text))
def _display_available_roles(self, list_json):
"""Display all roles we can find with a valid argument specification.
Output is: fqcn role name, entry point, short description
"""
roles = list(list_json.keys())
entry_point_names = set() # to find max len
for role in roles:
for entry_point in list_json[role]['entry_points'].keys():
entry_point_names.add(entry_point)
max_role_len = 0
max_ep_len = 0
if entry_point_names:
max_ep_len = max(len(x) for x in entry_point_names)
linelimit = display.columns - max_role_len - max_ep_len - 5
text = []
for role in sorted(roles):
if list_json[role]['entry_points']:
text.append('%s:' % role)
text.append(' specs:')
for entry_point, desc in list_json[role]['entry_points'].items():
if len(desc) > linelimit:
desc = desc[:linelimit] + '...'
text.append(" %-*s: %s" % (max_ep_len, entry_point, desc))
else:
text.append('%s' % role)
# display results
DocCLI.pager("\n".join(text))
def _display_role_doc(self, role_json):
roles = list(role_json.keys())
text = []
for role in roles:
try:
if 'error' in role_json[role]:
display.warning("Skipping role '%s' due to: %s" % (role, role_json[role]['error']), True)
continue
text += self.get_role_man_text(role, role_json[role])
except AnsibleError as ex:
# TODO: warn and skip role?
raise AnsibleParserError(f"Error extracting role docs from {role!r}.") from ex
# display results
DocCLI.pager("\n".join(text))
@staticmethod
def _list_keywords():
return yaml.load(pkgutil.get_data('ansible', 'keyword_desc.yml'), Loader=AnsibleInstrumentedLoader)
@staticmethod
def _get_keywords_docs(keys):
data = {}
descs = DocCLI._list_keywords()
for key in keys:
if key.startswith('with_'):
# simplify loops, dont want to handle every with_ combo
keyword = 'loop'
elif key == 'async':
# cause async became reserved in python we had to rename internally
keyword = 'async_val'
else:
keyword = key
try:
# if no desc, typeerror raised ends this block
kdata = {'description': descs[key]}
# get playbook objects for keyword and use first to get keyword attributes
kdata['applies_to'] = []
for pobj in PB_OBJECTS:
if pobj not in PB_LOADED:
obj_class = 'ansible.playbook.%s' % pobj.lower()
loaded_class = importlib.import_module(obj_class)
PB_LOADED[pobj] = getattr(loaded_class, pobj, None)
if keyword in PB_LOADED[pobj].fattributes:
kdata['applies_to'].append(pobj)
# we should only need these once
if 'type' not in kdata:
fa = PB_LOADED[pobj].fattributes.get(keyword)
if getattr(fa, 'private'):
kdata = {}
raise KeyError
kdata['type'] = getattr(fa, 'isa', 'string')
if keyword.endswith('when') or keyword in ('until',):
# TODO: make this a field attribute property,
# would also helps with the warnings on {{}} stacking
kdata['template'] = 'implicit'
elif getattr(fa, 'static'):
kdata['template'] = 'static'
else:
kdata['template'] = 'explicit'
# those that require no processing
for visible in ('alias', 'priority'):
kdata[visible] = getattr(fa, visible)
# remove None keys
for k in list(kdata.keys()):
if kdata[k] is None:
del kdata[k]
data[key] = kdata
except (AttributeError, KeyError) as ex:
display.error_as_warning(f'Skipping invalid keyword {key!r}.', ex)
return data
def _get_collection_filter(self):
coll_filter = None
if len(context.CLIARGS['args']) >= 1:
coll_filter = context.CLIARGS['args']
for coll_name in coll_filter:
if not AnsibleCollectionRef.is_valid_collection_name(coll_name):
raise AnsibleError('Invalid collection name (must be of the form namespace.collection): {0}'.format(coll_name))
return coll_filter
def _list_plugins(self, plugin_type, content):
results = {}
self.plugins = {}
loader = DocCLI._prep_loader(plugin_type)
coll_filter = self._get_collection_filter()
self.plugins.update(list_plugins(plugin_type, coll_filter))
# get appropriate content depending on option
if content == 'dir':
results = self._get_plugin_list_descriptions(loader)
elif content == 'files':
results = {k: self.plugins[k][0] for k in self.plugins.keys()}
else:
results = {k: {} for k in self.plugins.keys()}
self.plugin_list = set() # reset for next iteration
return results
def _get_plugins_docs(self, plugin_type, names, fail_ok=False, fail_on_errors=True):
loader = DocCLI._prep_loader(plugin_type)
# get the docs for plugins in the command line list
plugin_docs = {}
for plugin in names:
doc = {}
try:
doc, plainexamples, returndocs, metadata = get_plugin_docs(plugin, plugin_type, loader, fragment_loader, (context.CLIARGS['verbosity'] > 0))
except AnsiblePluginNotFound as e:
display.warning(to_native(e))
continue
except Exception as ex:
msg = "Missing documentation (or could not parse documentation)"
if not fail_on_errors:
plugin_docs[plugin] = {'error': f'{msg}: {ex}.'}
continue
msg = f"{plugin_type} {plugin} {msg}"
if fail_ok:
display.warning(f'{msg}: {ex}')
else:
raise AnsibleError(f'{msg}.') from ex
if not doc:
# The doc section existed but was empty
if not fail_on_errors:
plugin_docs[plugin] = {'error': 'No valid documentation found'}
continue
docs = DocCLI._combine_plugin_doc(plugin, plugin_type, doc, plainexamples, returndocs, metadata)
if not fail_on_errors:
# Check whether JSON serialization would break
try:
_json.json_dumps_formatted(docs)
except Exception as ex: # pylint:disable=broad-except
plugin_docs[plugin] = {'error': f'Cannot serialize documentation as JSON: {ex}'}
continue
plugin_docs[plugin] = docs
return plugin_docs
def _get_roles_path(self):
"""
Add any 'roles' subdir in playbook dir to the roles search path.
And as a last resort, add the playbook dir itself. Order being:
- 'roles' subdir of playbook dir
- DEFAULT_ROLES_PATH (default in cliargs)
- playbook dir (basedir)
NOTE: This matches logic in RoleDefinition._load_role_path() method.
"""
roles_path = context.CLIARGS['roles_path']
if context.CLIARGS['basedir'] is not None:
subdir = os.path.join(context.CLIARGS['basedir'], "roles")
if os.path.isdir(subdir):
roles_path = (subdir,) + roles_path
roles_path = roles_path + (context.CLIARGS['basedir'],)
return roles_path
@staticmethod
def _prep_loader(plugin_type):
""" return a plugint type specific loader """
loader = getattr(plugin_loader, '%s_loader' % plugin_type)
# add to plugin paths from command line
if context.CLIARGS['basedir'] is not None:
loader.add_directory(context.CLIARGS['basedir'], with_subdir=True)
if context.CLIARGS['module_path']:
for path in context.CLIARGS['module_path']:
if path:
loader.add_directory(path)
# save only top level paths for errors
loader._paths = None # reset so we can use subdirs later
return loader
def run(self):
super(DocCLI, self).run()
basedir = context.CLIARGS['basedir']
plugin_type = context.CLIARGS['type'].lower()
do_json = context.CLIARGS['json_format'] or context.CLIARGS['dump']
listing = context.CLIARGS['list_files'] or context.CLIARGS['list_dir']
no_fail = bool(not context.CLIARGS['no_fail_on_errors'])
if context.CLIARGS['list_files']:
content = 'files'
elif context.CLIARGS['list_dir']:
content = 'dir'
else:
content = None
docs = {}
if basedir:
AnsibleCollectionConfig.playbook_paths = basedir
if plugin_type not in TARGET_OPTIONS:
raise AnsibleOptionsError("Unknown or undocumentable plugin type: %s" % plugin_type)
if context.CLIARGS['dump']:
# we always dump all types, ignore restrictions
ptypes = TARGET_OPTIONS
docs['all'] = {}
for ptype in ptypes:
if ptype == 'role':
roles = self._create_role_list(fail_on_errors=no_fail)
docs['all'][ptype] = self._create_role_doc(roles.keys(), context.CLIARGS['entry_point'], fail_on_errors=no_fail)
elif ptype == 'keyword':
names = DocCLI._list_keywords()
docs['all'][ptype] = DocCLI._get_keywords_docs(names.keys())
else:
plugin_names = self._list_plugins(ptype, None)
docs['all'][ptype] = self._get_plugins_docs(ptype, plugin_names, fail_ok=(ptype in ('test', 'filter')), fail_on_errors=no_fail)
# reset list after each type to avoid pollution
elif listing:
if plugin_type == 'keyword':
docs = DocCLI._list_keywords()
elif plugin_type == 'role':
docs = self._create_role_list(fail_on_errors=False)
else:
docs = self._list_plugins(plugin_type, content)
else:
# here we require a name
if len(context.CLIARGS['args']) == 0:
raise AnsibleOptionsError("Missing name(s), incorrect options passed for detailed documentation.")
if plugin_type == 'keyword':
docs = DocCLI._get_keywords_docs(context.CLIARGS['args'])
elif plugin_type == 'role':
docs = self._create_role_doc(context.CLIARGS['args'], context.CLIARGS['entry_point'], fail_on_errors=no_fail)
else:
# display specific plugin docs
docs = self._get_plugins_docs(plugin_type, context.CLIARGS['args'])
# Display the docs
if do_json:
jdump(docs)
else:
text = []
if plugin_type in C.DOCUMENTABLE_PLUGINS:
if listing and docs:
self.display_plugin_list(docs)
elif context.CLIARGS['show_snippet']:
if plugin_type not in SNIPPETS:
raise AnsibleError('Snippets are only available for the following plugin'
' types: %s' % ', '.join(SNIPPETS))
for plugin, doc_data in docs.items():
try:
textret = DocCLI.format_snippet(plugin, plugin_type, doc_data['doc'])
except ValueError as e:
display.warning("Unable to construct a snippet for"
" '{0}': {1}".format(plugin, to_text(e)))
else:
text.append(textret)
else:
# Some changes to how plain text docs are formatted
for plugin, doc_data in docs.items():
textret = DocCLI.format_plugin_doc(plugin, plugin_type,
doc_data['doc'], doc_data['examples'],
doc_data['return'], doc_data['metadata'])
if textret:
text.append(textret)
else:
display.warning("No valid documentation was retrieved from '%s'" % plugin)
elif plugin_type == 'role':
if context.CLIARGS['list_dir'] and docs:
self._display_available_roles(docs)
elif docs:
self._display_role_doc(docs)
elif docs:
text = DocCLI.tty_ify(DocCLI._dump_yaml(docs))
if text:
DocCLI.pager(''.join(text))
return 0
@staticmethod
def get_all_plugins_of_type(plugin_type):
loader = getattr(plugin_loader, '%s_loader' % plugin_type)
paths = loader._get_paths_with_context()
plugins = {}
for path_context in paths:
plugins.update(list_plugins(plugin_type))
return sorted(plugins.keys())
@staticmethod
def get_plugin_metadata(plugin_type, plugin_name):
# if the plugin lives in a non-python file (eg, win_X.ps1), require the corresponding python file for docs
loader = getattr(plugin_loader, '%s_loader' % plugin_type)
result = loader.find_plugin_with_context(plugin_name, mod_type='.py', ignore_deprecated=True, check_aliases=True)
if not result.resolved:
raise AnsibleError("unable to load {0} plugin named {1} ".format(plugin_type, plugin_name))
filename = result.plugin_resolved_path
collection_name = result.plugin_resolved_collection
try:
doc, __, __, __ = get_docstring(filename, fragment_loader, verbose=(context.CLIARGS['verbosity'] > 0),
collection_name=collection_name, plugin_type=plugin_type)
except Exception as ex:
raise AnsibleError(f"{plugin_type} {plugin_name} at {filename!r} has a documentation formatting error or is missing documentation.") from ex
if doc is None:
# Removed plugins don't have any documentation
return None
return dict(
name=plugin_name,
namespace=DocCLI.namespace_from_plugin_filepath(filename, plugin_name, loader.package_path),
description=doc.get('short_description', "UNKNOWN"),
version_added=doc.get('version_added', "UNKNOWN")
)
@staticmethod
def namespace_from_plugin_filepath(filepath, plugin_name, basedir):
if not basedir.endswith('/'):
basedir += '/'
rel_path = filepath.replace(basedir, '')
extension_free = os.path.splitext(rel_path)[0]
namespace_only = extension_free.rsplit(plugin_name, 1)[0].strip('/_')
clean_ns = namespace_only.replace('/', '.')
if clean_ns == '':
clean_ns = None
return clean_ns
@staticmethod
def _combine_plugin_doc(plugin, plugin_type, doc, plainexamples, returndocs, metadata):
# generate extra data
if plugin_type == 'module':
# is there corresponding action plugin?
if plugin in action_loader:
doc['has_action'] = True
else:
doc['has_action'] = False
# return everything as one dictionary
return {'doc': doc, 'examples': plainexamples, 'return': returndocs, 'metadata': metadata}
@staticmethod
def format_snippet(plugin, plugin_type, doc):
""" return heavily commented plugin use to insert into play """
if plugin_type == 'inventory' and doc.get('options', {}).get('plugin'):
# these do not take a yaml config that we can write a snippet for
raise ValueError('The {0} inventory plugin does not take YAML type config source'
' that can be used with the "auto" plugin so a snippet cannot be'
' created.'.format(plugin))
text = []
if plugin_type == 'lookup':
text = _do_lookup_snippet(doc)
elif 'options' in doc:
text = _do_yaml_snippet(doc)
text.append('')
return "\n".join(text)
@staticmethod
def format_plugin_doc(plugin, plugin_type, doc, plainexamples, returndocs, metadata):
collection_name = doc['collection']
# TODO: do we really want this?
# add_collection_to_versions_and_dates(doc, '(unknown)', is_module=(plugin_type == 'module'))
# remove_current_collection_from_versions_and_dates(doc, collection_name, is_module=(plugin_type == 'module'))
# remove_current_collection_from_versions_and_dates(
# returndocs, collection_name, is_module=(plugin_type == 'module'), return_docs=True)
# assign from other sections
doc['plainexamples'] = plainexamples
doc['returndocs'] = returndocs
doc['metadata'] = metadata
try:
text = DocCLI.get_man_text(doc, collection_name, plugin_type)
except Exception as ex:
raise AnsibleError(f"Unable to retrieve documentation from {plugin!r}.") from ex
return text
def _get_plugin_list_descriptions(self, loader):
descs = {}
for plugin in self.plugins.keys():
# TODO: move to plugin itself i.e: plugin.get_desc()
doc = None
filename = Path(to_native(self.plugins[plugin][0]))
docerror = None
try:
doc = read_docstub(filename)
except Exception as e:
docerror = e
# plugin file was empty or had error, lets try other options
if doc is None:
# handle test/filters that are in file with diff name
base = plugin.split('.')[-1]
basefile = filename.with_name(base + filename.suffix)
for extension in C.DOC_EXTENSIONS:
docfile = basefile.with_suffix(extension)
try:
if docfile.exists():
doc = read_docstub(docfile)
except Exception as e:
docerror = e
if docerror:
display.warning("%s has a documentation formatting error: %s" % (plugin, docerror))
continue
if not doc or not isinstance(doc, dict):
desc = 'UNDOCUMENTED'
else:
desc = doc.get('short_description', 'INVALID SHORT DESCRIPTION').strip()
descs[plugin] = desc
return descs
@staticmethod
def print_paths(finder):
""" Returns a string suitable for printing of the search path """
# Uses a list to get the order right
ret = []
for i in finder._get_paths(subdirs=False):
i = to_text(i, errors='surrogate_or_strict')
if i not in ret:
ret.append(i)
return os.pathsep.join(ret)
@staticmethod
def _dump_yaml(struct, flow_style=False):
return yaml_dump(struct, default_flow_style=flow_style, default_style="''", Dumper=AnsibleDumper).rstrip('\n')
@staticmethod
def _indent_lines(text, indent):
return DocCLI.tty_ify('\n'.join([indent + line for line in text.split('\n')]))
@staticmethod
def _format_version_added(version_added, version_added_collection=None):
if version_added_collection == 'ansible.builtin':
version_added_collection = 'ansible-core'
# In ansible-core, version_added can be 'historical'
if version_added == 'historical':
return 'historical'
if version_added_collection:
version_added = '%s of %s' % (version_added, version_added_collection)
return 'version %s' % (version_added, )
@staticmethod
def warp_fill(text, limit, initial_indent='', subsequent_indent='', initial_extra=0, **kwargs):
result = []
for paragraph in text.split('\n\n'):
wrapped = textwrap.fill(paragraph, limit, initial_indent=initial_indent + ' ' * initial_extra, subsequent_indent=subsequent_indent,
break_on_hyphens=False, break_long_words=False, drop_whitespace=True, **kwargs)
if initial_extra and wrapped.startswith(' ' * initial_extra):
wrapped = wrapped[initial_extra:]
result.append(wrapped)
initial_indent = subsequent_indent
initial_extra = 0
return '\n'.join(result)
@staticmethod
def add_fields(text, fields, limit, opt_indent, return_values=False, base_indent='', man=False):
for o in sorted(fields):
# Create a copy so we don't modify the original (in case YAML anchors have been used)
opt = dict(fields[o])
# required is used as indicator and removed
required = opt.pop('required', False)
if not isinstance(required, bool):
raise AnsibleError("Incorrect value for 'Required', a boolean is needed.: %s" % required)
opt_leadin = ' '
key = ''
if required:
if C.ANSIBLE_NOCOLOR:
opt_leadin = "="
key = "%s%s %s" % (base_indent, opt_leadin, _format(o, 'bold', 'red'))
else:
if C.ANSIBLE_NOCOLOR:
opt_leadin = "-"
key = "%s%s %s" % (base_indent, opt_leadin, _format(o, 'yellow'))
# description is specifically formatted and can either be string or list of strings
if 'description' not in opt:
raise AnsibleError("All (sub-)options and return values must have a 'description' field")
text.append('')
# TODO: push this to top of for and sort by size, create indent on largest key?
inline_indent = ' ' * max((len(opt_indent) - len(o)) - len(base_indent), 2)
extra_indent = base_indent + ' ' * (len(o) + 3)
sub_indent = inline_indent + extra_indent
if is_sequence(opt['description']):
for entry_idx, entry in enumerate(opt['description'], 1):
if not isinstance(entry, string_types):
raise AnsibleError("Expected string in description of %s at index %s, got %s" % (o, entry_idx, type(entry)))
if entry_idx == 1:
text.append(key + DocCLI.warp_fill(DocCLI.tty_ify(entry), limit,
initial_indent=inline_indent, subsequent_indent=sub_indent, initial_extra=len(extra_indent)))
else:
text.append(DocCLI.warp_fill(DocCLI.tty_ify(entry), limit, initial_indent=sub_indent, subsequent_indent=sub_indent))
else:
if not isinstance(opt['description'], string_types):
raise AnsibleError("Expected string in description of %s, got %s" % (o, type(opt['description'])))
text.append(key + DocCLI.warp_fill(DocCLI.tty_ify(opt['description']), limit,
initial_indent=inline_indent, subsequent_indent=sub_indent, initial_extra=len(extra_indent)))
del opt['description']
suboptions = []
for subkey in ('options', 'suboptions', 'contains', 'spec'):
if subkey in opt:
suboptions.append((subkey, opt.pop(subkey)))
if not required and not return_values and 'default' not in opt:
opt['default'] = None
# sanitize config items
conf = {}
for config in ('env', 'ini', 'yaml', 'vars', 'keyword'):
if config in opt and opt[config]:
# Create a copy so we don't modify the original (in case YAML anchors have been used)
conf[config] = [dict(item) for item in opt.pop(config)]
for ignore in DocCLI.IGNORE:
for item in conf[config]:
if display.verbosity > 0 and 'version_added' in item:
item['added_in'] = DocCLI._format_version_added(item['version_added'], item.get('version_added_colleciton', 'ansible-core'))
if ignore in item:
del item[ignore]
# reformat cli optoins
if 'cli' in opt and opt['cli']:
conf['cli'] = []
for cli in opt['cli']:
if 'option' not in cli:
conf['cli'].append({'name': cli['name'], 'option': '--%s' % cli['name'].replace('_', '-')})
else:
conf['cli'].append(cli)
del opt['cli']
# add custom header for conf
if conf:
text.append(DocCLI._indent_lines(DocCLI._dump_yaml({'set_via': conf}), opt_indent))
# these we handle at the end of generic option processing
version_added = opt.pop('version_added', None)
version_added_collection = opt.pop('version_added_collection', None)
# general processing for options
for k in sorted(opt):
if k.startswith('_'):
continue
if is_sequence(opt[k]):
text.append(DocCLI._indent_lines('%s: %s' % (k, DocCLI._dump_yaml(opt[k], flow_style=True)), opt_indent))
else:
text.append(DocCLI._indent_lines(DocCLI._dump_yaml({k: opt[k]}), opt_indent))
if version_added and not man:
text.append("%sadded in: %s" % (opt_indent, DocCLI._format_version_added(version_added, version_added_collection)))
for subkey, subdata in suboptions:
text.append("%s%s:" % (opt_indent, subkey))
DocCLI.add_fields(text, subdata, limit, opt_indent + ' ', return_values, opt_indent)
def get_role_man_text(self, role, role_json):
"""Generate text for the supplied role suitable for display.
This is similar to get_man_text(), but roles are different enough that we have
a separate method for formatting their display.
:param role: The role name.
:param role_json: The JSON for the given role as returned from _create_role_doc().
:returns: A array of text suitable for displaying to screen.
"""
text = []
opt_indent = " "
pad = display.columns * 0.20
limit = max(display.columns - int(pad), 70)
text.append("> ROLE: %s (%s)" % (_format(role, 'BOLD'), role_json.get('path')))
for entry_point in role_json['entry_points']:
doc = role_json['entry_points'][entry_point]
desc = ''
if doc.get('short_description'):
desc = "- %s" % (doc.get('short_description'))
text.append('')
text.append("ENTRY POINT: %s %s" % (_format(entry_point, "BOLD"), desc))
text.append('')
if doc.get('description'):
if isinstance(doc['description'], list):
descs = doc['description']
else:
descs = [doc['description']]
for desc in descs:
text.append("%s" % DocCLI.warp_fill(DocCLI.tty_ify(desc), limit, initial_indent=opt_indent, subsequent_indent=opt_indent))
text.append('')
if doc.get('options'):
text.append(_format("Options", 'bold') + " (%s indicates it is required):" % ("=" if C.ANSIBLE_NOCOLOR else 'red'))
DocCLI.add_fields(text, doc.pop('options'), limit, opt_indent)
if doc.get('attributes', False):
display.deprecated(
f'The role {role}\'s argument spec {entry_point} contains the key "attributes", '
'which will not be displayed by ansible-doc in the future. '
'This was unintentionally allowed when plugin attributes were added, '
'but the feature does not map well to role argument specs.',
version='2.20',
)
text.append("")
text.append(_format("ATTRIBUTES:", 'bold'))
for k in doc['attributes'].keys():
text.append('')
text.append(DocCLI.warp_fill(DocCLI.tty_ify(_format('%s:' % k, 'UNDERLINE')), limit - 6, initial_indent=opt_indent,
subsequent_indent=opt_indent))
text.append(DocCLI._indent_lines(DocCLI._dump_yaml(doc['attributes'][k]), opt_indent))
del doc['attributes']
# generic elements we will handle identically
for k in ('author',):
if k not in doc:
continue
text.append('')
if isinstance(doc[k], string_types):
text.append('%s: %s' % (k.upper(), DocCLI.warp_fill(DocCLI.tty_ify(doc[k]),
limit - (len(k) + 2), subsequent_indent=opt_indent)))
elif isinstance(doc[k], (list, tuple)):
text.append('%s: %s' % (k.upper(), ', '.join(doc[k])))
else:
# use empty indent since this affects the start of the yaml doc, not it's keys
text.append(DocCLI._indent_lines(DocCLI._dump_yaml({k.upper(): doc[k]}), ''))
if doc.get('examples', False):
text.append('')
text.append(_format("EXAMPLES:", 'bold'))
if isinstance(doc['examples'], string_types):
text.append(doc.pop('examples').strip())
else:
try:
text.append(yaml_dump(doc.pop('examples'), indent=2, default_flow_style=False))
except Exception as e:
raise AnsibleParserError("Unable to parse examples section", orig_exc=e)
return text
@staticmethod
def get_man_text(doc, collection_name='', plugin_type=''):
# Create a copy so we don't modify the original
doc = dict(doc)
DocCLI.IGNORE = DocCLI.IGNORE + (context.CLIARGS['type'],)
opt_indent = " "
base_indent = " "
text = []
pad = display.columns * 0.20
limit = max(display.columns - int(pad), 70)
text.append("> %s %s (%s)" % (plugin_type.upper(), _format(doc.pop('plugin_name'), 'bold'), doc.pop('filename')))
if isinstance(doc['description'], list):
descs = doc.pop('description')
else:
descs = [doc.pop('description')]
text.append('')
for desc in descs:
text.append(DocCLI.warp_fill(DocCLI.tty_ify(desc), limit, initial_indent=base_indent, subsequent_indent=base_indent))
if display.verbosity > 0:
doc['added_in'] = DocCLI._format_version_added(doc.pop('version_added', 'historical'), doc.pop('version_added_collection', 'ansible-core'))
if doc.get('deprecated', False):
text.append(_format("DEPRECATED: ", 'bold', 'DEP'))
if isinstance(doc['deprecated'], dict):
if 'removed_at_date' not in doc['deprecated'] and 'version' in doc['deprecated'] and 'removed_in' not in doc['deprecated']:
doc['deprecated']['removed_in'] = doc['deprecated']['version']
try:
text.append('\t' + C.config.get_deprecated_msg_from_config(doc['deprecated'], True, collection_name=collection_name))
except KeyError as e:
raise AnsibleError("Invalid deprecation documentation structure", orig_exc=e)
else:
text.append("%s" % doc['deprecated'])
del doc['deprecated']
if doc.pop('has_action', False):
text.append("")
text.append(_format(" * note:", 'bold') + " This module has a corresponding action plugin.")
if doc.get('options', False):
text.append("")
text.append(_format("OPTIONS", 'bold') + " (%s indicates it is required):" % ("=" if C.ANSIBLE_NOCOLOR else 'red'))
DocCLI.add_fields(text, doc.pop('options'), limit, opt_indent, man=(display.verbosity == 0))
if doc.get('attributes', False):
text.append("")
text.append(_format("ATTRIBUTES:", 'bold'))
for k in doc['attributes'].keys():
text.append('')
text.append(DocCLI.warp_fill(DocCLI.tty_ify(_format('%s:' % k, 'UNDERLINE')), limit - 6, initial_indent=opt_indent,
subsequent_indent=opt_indent))
text.append(DocCLI._indent_lines(DocCLI._dump_yaml(doc['attributes'][k]), opt_indent))
del doc['attributes']
if doc.get('notes', False):
text.append("")
text.append(_format("NOTES:", 'bold'))
for note in doc['notes']:
text.append(DocCLI.warp_fill(DocCLI.tty_ify(note), limit - 6,
initial_indent=opt_indent[:-2] + "* ", subsequent_indent=opt_indent))
del doc['notes']
if doc.get('seealso', False):
text.append("")
text.append(_format("SEE ALSO:", 'bold'))
for item in doc['seealso']:
if 'module' in item:
text.append(DocCLI.warp_fill(DocCLI.tty_ify('Module %s' % item['module']),
limit - 6, initial_indent=opt_indent[:-2] + "* ", subsequent_indent=opt_indent))
description = item.get('description')
if description is None and item['module'].startswith('ansible.builtin.'):
description = 'The official documentation on the %s module.' % item['module']
if description is not None:
text.append(DocCLI.warp_fill(DocCLI.tty_ify(description),
limit - 6, initial_indent=opt_indent + ' ', subsequent_indent=opt_indent + ' '))
if item['module'].startswith('ansible.builtin.'):
relative_url = 'collections/%s_module.html' % item['module'].replace('.', '/', 2)
text.append(DocCLI.warp_fill(DocCLI.tty_ify(get_versioned_doclink(relative_url)),
limit - 6, initial_indent=opt_indent + ' ', subsequent_indent=opt_indent))
elif 'plugin' in item and 'plugin_type' in item:
plugin_suffix = ' plugin' if item['plugin_type'] not in ('module', 'role') else ''
text.append(DocCLI.warp_fill(DocCLI.tty_ify('%s%s %s' % (item['plugin_type'].title(), plugin_suffix, item['plugin'])),
limit - 6, initial_indent=opt_indent[:-2] + "* ", subsequent_indent=opt_indent))
description = item.get('description')
if description is None and item['plugin'].startswith('ansible.builtin.'):
description = 'The official documentation on the %s %s%s.' % (item['plugin'], item['plugin_type'], plugin_suffix)
if description is not None:
text.append(DocCLI.warp_fill(DocCLI.tty_ify(description),
limit - 6, initial_indent=opt_indent + ' ', subsequent_indent=opt_indent + ' '))
if item['plugin'].startswith('ansible.builtin.'):
relative_url = 'collections/%s_%s.html' % (item['plugin'].replace('.', '/', 2), item['plugin_type'])
text.append(DocCLI.warp_fill(DocCLI.tty_ify(get_versioned_doclink(relative_url)),
limit - 6, initial_indent=opt_indent + ' ', subsequent_indent=opt_indent))
elif 'name' in item and 'link' in item and 'description' in item:
text.append(DocCLI.warp_fill(DocCLI.tty_ify(item['name']),
limit - 6, initial_indent=opt_indent[:-2] + "* ", subsequent_indent=opt_indent))
text.append(DocCLI.warp_fill(DocCLI.tty_ify(item['description']),
limit - 6, initial_indent=opt_indent + ' ', subsequent_indent=opt_indent + ' '))
text.append(DocCLI.warp_fill(DocCLI.tty_ify(item['link']),
limit - 6, initial_indent=opt_indent + ' ', subsequent_indent=opt_indent + ' '))
elif 'ref' in item and 'description' in item:
text.append(DocCLI.warp_fill(DocCLI.tty_ify('Ansible documentation [%s]' % item['ref']),
limit - 6, initial_indent=opt_indent[:-2] + "* ", subsequent_indent=opt_indent))
text.append(DocCLI.warp_fill(DocCLI.tty_ify(item['description']),
limit - 6, initial_indent=opt_indent + ' ', subsequent_indent=opt_indent + ' '))
text.append(DocCLI.warp_fill(DocCLI.tty_ify(get_versioned_doclink('/#stq=%s&stp=1' % item['ref'])),
limit - 6, initial_indent=opt_indent + ' ', subsequent_indent=opt_indent + ' '))
del doc['seealso']
if doc.get('requirements', False):
text.append('')
req = ", ".join(doc.pop('requirements'))
text.append(_format("REQUIREMENTS:", 'bold') + "%s\n" % DocCLI.warp_fill(DocCLI.tty_ify(req), limit - 16, initial_indent=" ",
subsequent_indent=opt_indent))
# Generic handler
for k in sorted(doc):
if not doc[k] or k in DocCLI.IGNORE:
continue
text.append('')
header = _format(k.upper(), 'bold')
if isinstance(doc[k], string_types):
text.append('%s: %s' % (header, DocCLI.warp_fill(DocCLI.tty_ify(doc[k]), limit - (len(k) + 2), subsequent_indent=opt_indent)))
elif isinstance(doc[k], (list, tuple)):
text.append('%s: %s' % (header, ', '.join(doc[k])))
else:
# use empty indent since this affects the start of the yaml doc, not it's keys
text.append('%s: ' % header + DocCLI._indent_lines(DocCLI._dump_yaml(doc[k]), ' ' * (len(k) + 2)))
del doc[k]
if doc.get('plainexamples', False):
text.append('')
text.append(_format("EXAMPLES:", 'bold'))
if isinstance(doc['plainexamples'], string_types):
text.append(doc.pop('plainexamples').strip())
else:
try:
text.append(yaml_dump(doc.pop('plainexamples'), indent=2, default_flow_style=False))
except Exception as ex:
raise AnsibleParserError("Unable to parse examples section.") from ex
if doc.get('returndocs', False):
text.append('')
text.append(_format("RETURN VALUES:", 'bold'))
DocCLI.add_fields(text, doc.pop('returndocs'), limit, opt_indent, return_values=True, man=(display.verbosity == 0))
text.append('\n')
return "\n".join(text)
def _do_yaml_snippet(doc):
text = []
mdesc = DocCLI.tty_ify(doc['short_description'])
module = doc.get('module')
if module:
# this is actually a usable task!
text.append("- name: %s" % (mdesc))
text.append(" %s:" % (module))
else:
# just a comment, hopefully useful yaml file
text.append("# %s:" % doc.get('plugin', doc.get('name')))
pad = 29
subdent = '# '.rjust(pad + 2)
limit = display.columns - pad
for o in sorted(doc['options'].keys()):
opt = doc['options'][o]
if isinstance(opt['description'], string_types):
desc = DocCLI.tty_ify(opt['description'])
else:
desc = DocCLI.tty_ify(" ".join(opt['description']))
required = opt.get('required', False)
if not isinstance(required, bool):
raise ValueError("Incorrect value for 'Required', a boolean is needed: %s" % required)
o = '%s:' % o
if module:
if required:
desc = "(required) %s" % desc
text.append(" %-20s # %s" % (o, DocCLI.warp_fill(desc, limit, subsequent_indent=subdent)))
else:
if required:
default = '(required)'
else:
default = opt.get('default', 'None')
text.append("%s %-9s # %s" % (o, default, DocCLI.warp_fill(desc, limit, subsequent_indent=subdent, max_lines=3)))
return text
def _do_lookup_snippet(doc):
text = []
snippet = "lookup('%s', " % doc.get('plugin', doc.get('name'))
comment = []
for o in sorted(doc['options'].keys()):
opt = doc['options'][o]
comment.append('# %s(%s): %s' % (o, opt.get('type', 'string'), opt.get('description', '')))
if o in ('_terms', '_raw', '_list'):
# these are 'list of arguments'
snippet += '< %s >' % (o)
continue
required = opt.get('required', False)
if not isinstance(required, bool):
raise ValueError("Incorrect value for 'Required', a boolean is needed: %s" % required)
if required:
default = ''
else:
default = opt.get('default', 'None')
if opt.get('type') in ('string', 'str'):
snippet += ", %s='%s'" % (o, default)
else:
snippet += ', %s=%s' % (o, default)
snippet += ")"
if comment:
text.extend(comment)
text.append('')
text.append(snippet)
return text
def main(args=None):
DocCLI.cli_executor(args)
if __name__ == '__main__':
main()
ansible_core-2.19.0b4/lib/ansible/cli/galaxy.py 0000755 0000000 0000000 00000272016 15010426755 020025 0 ustar 00root root #!/usr/bin/env python
# Copyright: (c) 2013, James Cammarata
# Copyright: (c) 2018-2021, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# PYTHON_ARGCOMPLETE_OK
from __future__ import annotations
# ansible.cli needs to be imported first, to ensure the source bin/* scripts run that code first
from ansible.cli import CLI
import argparse
import functools
import json
import os.path
import pathlib
import re
import shutil
import sys
import textwrap
import time
import typing as t
from dataclasses import dataclass
from yaml.error import YAMLError
import ansible.constants as C
from ansible import context
from ansible.cli.arguments import option_helpers as opt_help
from ansible.errors import AnsibleError, AnsibleOptionsError
from ansible.galaxy import Galaxy, get_collections_galaxy_meta_info
from ansible.galaxy.api import GalaxyAPI, GalaxyError
from ansible.galaxy.collection import (
build_collection,
download_collections,
find_existing_collections,
install_collections,
publish_collection,
validate_collection_name,
validate_collection_path,
verify_collections,
SIGNATURE_COUNT_RE,
)
from ansible.galaxy.collection.concrete_artifact_manager import (
ConcreteArtifactsManager,
)
from ansible.galaxy.collection.gpg import GPG_ERROR_MAP
from ansible.galaxy.dependency_resolution.dataclasses import Requirement
from ansible.galaxy.role import GalaxyRole
from ansible.galaxy.token import BasicAuthToken, GalaxyToken, KeycloakToken, NoTokenSentinel
from ansible.module_utils.ansible_release import __version__ as ansible_version
from ansible.module_utils.common.collections import is_iterable
from ansible.module_utils.common.yaml import yaml_dump, yaml_load
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
from ansible._internal._datatag._tags import TrustedAsTemplate
from ansible.module_utils import six
from ansible.parsing.dataloader import DataLoader
from ansible.playbook.role.requirement import RoleRequirement
from ansible._internal._templating._engine import TemplateEngine
from ansible.template import trust_as_template
from ansible.utils.collection_loader import AnsibleCollectionConfig
from ansible.utils.display import Display
from ansible.utils.plugin_docs import get_versioned_doclink
from ansible.utils.vars import load_extra_vars
display = Display()
urlparse = six.moves.urllib.parse.urlparse
def with_collection_artifacts_manager(wrapped_method):
"""Inject an artifacts manager if not passed explicitly.
This decorator constructs a ConcreteArtifactsManager and maintains
the related temporary directory auto-cleanup around the target
method invocation.
"""
@functools.wraps(wrapped_method)
def method_wrapper(*args, **kwargs):
if 'artifacts_manager' in kwargs:
return wrapped_method(*args, **kwargs)
# FIXME: use validate_certs context from Galaxy servers when downloading collections
# .get used here for when this is used in a non-CLI context
artifacts_manager_kwargs = {'validate_certs': context.CLIARGS.get('resolved_validate_certs', True)}
keyring = context.CLIARGS.get('keyring', None)
if keyring is not None:
artifacts_manager_kwargs.update({
'keyring': GalaxyCLI._resolve_path(keyring),
'required_signature_count': context.CLIARGS.get('required_valid_signature_count', None),
'ignore_signature_errors': context.CLIARGS.get('ignore_gpg_errors', None),
})
with ConcreteArtifactsManager.under_tmpdir(
C.DEFAULT_LOCAL_TMP,
**artifacts_manager_kwargs
) as concrete_artifact_cm:
kwargs['artifacts_manager'] = concrete_artifact_cm
return wrapped_method(*args, **kwargs)
return method_wrapper
def _display_header(path, h1, h2, w1=10, w2=7):
display.display('\n# {0}\n{1:{cwidth}} {2:{vwidth}}\n{3} {4}\n'.format(
path,
h1,
h2,
'-' * max([len(h1), w1]), # Make sure that the number of dashes is at least the width of the header
'-' * max([len(h2), w2]),
cwidth=w1,
vwidth=w2,
))
def _display_role(gr):
install_info = gr.install_info
version = None
if install_info:
version = install_info.get("version", None)
if not version:
version = "(unknown version)"
display.display("- %s, %s" % (gr.name, version))
def _display_collection(collection, cwidth=10, vwidth=7, min_cwidth=10, min_vwidth=7):
display.display('{fqcn:{cwidth}} {version:{vwidth}}'.format(
fqcn=to_text(collection.fqcn),
version=collection.ver,
cwidth=max(cwidth, min_cwidth), # Make sure the width isn't smaller than the header
vwidth=max(vwidth, min_vwidth)
))
def _get_collection_widths(collections):
if not is_iterable(collections):
collections = (collections, )
fqcn_set = {to_text(c.fqcn) for c in collections}
version_set = {to_text(c.ver) for c in collections}
fqcn_length = len(max(fqcn_set or [''], key=len))
version_length = len(max(version_set or [''], key=len))
return fqcn_length, version_length
def validate_signature_count(value):
match = re.match(SIGNATURE_COUNT_RE, value)
if match is None:
raise ValueError(f"{value} is not a valid signature count value")
return value
@dataclass
class RoleDistributionServer:
_api: t.Union[GalaxyAPI, None]
api_servers: list[GalaxyAPI]
@property
def api(self):
if self._api:
return self._api
for server in self.api_servers:
try:
if u'v1' in server.available_api_versions:
self._api = server
break
except Exception:
continue
if not self._api:
self._api = self.api_servers[0]
return self._api
class GalaxyCLI(CLI):
"""Command to manage Ansible roles and collections.
None of the CLI tools are designed to run concurrently with themselves.
Use an external scheduler and/or locking to ensure there are no clashing operations.
"""
name = 'ansible-galaxy'
SKIP_INFO_KEYS = ("name", "description", "readme_html", "related", "summary_fields", "average_aw_composite", "average_aw_score", "url")
def __init__(self, args):
self._raw_args = args
self._implicit_role = False
if len(args) > 1:
# Inject role into sys.argv[1] as a backwards compatibility step
if args[1] not in ['-h', '--help', '--version'] and 'role' not in args and 'collection' not in args:
# TODO: Should we add a warning here and eventually deprecate the implicit role subcommand choice
args.insert(1, 'role')
self._implicit_role = True
# since argparse doesn't allow hidden subparsers, handle dead login arg from raw args after "role" normalization
if args[1:3] == ['role', 'login']:
display.error(
"The login command was removed in late 2020. An API key is now required to publish roles or collections "
"to Galaxy. The key can be found at https://galaxy.ansible.com/me/preferences, and passed to the "
"ansible-galaxy CLI via a file at {0} or (insecurely) via the `--token` "
"command-line argument.".format(to_text(C.GALAXY_TOKEN_PATH)))
sys.exit(1)
self.api_servers = []
self.galaxy = None
self.lazy_role_api = None
super(GalaxyCLI, self).__init__(args)
def init_parser(self):
""" create an options parser for bin/ansible """
super(GalaxyCLI, self).init_parser(
desc="Perform various Role and Collection related operations.",
)
# Common arguments that apply to more than 1 action
common = opt_help.ArgumentParser(add_help=False)
common.add_argument('-s', '--server', dest='api_server', help='The Galaxy API server URL')
common.add_argument('--api-version', type=int, choices=[2, 3], help=argparse.SUPPRESS) # Hidden argument that should only be used in our tests
common.add_argument('--token', '--api-key', dest='api_key',
help='The Ansible Galaxy API key which can be found at '
'https://galaxy.ansible.com/me/preferences.')
common.add_argument('-c', '--ignore-certs', action='store_true', dest='ignore_certs', help='Ignore SSL certificate validation errors.', default=None)
# --timeout uses the default None to handle two different scenarios.
# * --timeout > C.GALAXY_SERVER_TIMEOUT for non-configured servers
# * --timeout > server-specific timeout > C.GALAXY_SERVER_TIMEOUT for configured servers.
common.add_argument('--timeout', dest='timeout', type=int,
help="The time to wait for operations against the galaxy server, defaults to 60s.")
opt_help.add_verbosity_options(common)
force = opt_help.ArgumentParser(add_help=False)
force.add_argument('-f', '--force', dest='force', action='store_true', default=False,
help='Force overwriting an existing role or collection')
github = opt_help.ArgumentParser(add_help=False)
github.add_argument('github_user', help='GitHub username')
github.add_argument('github_repo', help='GitHub repository')
offline = opt_help.ArgumentParser(add_help=False)
offline.add_argument('--offline', dest='offline', default=False, action='store_true',
help="Don't query the galaxy API when creating roles")
default_roles_path = C.config.get_configuration_definition('DEFAULT_ROLES_PATH').get('default', '')
roles_path = opt_help.ArgumentParser(add_help=False)
roles_path.add_argument('-p', '--roles-path', dest='roles_path', type=opt_help.unfrack_path(pathsep=True),
default=C.DEFAULT_ROLES_PATH, action=opt_help.PrependListAction,
help='The path to the directory containing your roles. The default is the first '
'writable one configured via DEFAULT_ROLES_PATH: %s ' % default_roles_path)
collections_path = opt_help.ArgumentParser(add_help=False)
collections_path.add_argument('-p', '--collections-path', dest='collections_path', type=opt_help.unfrack_path(pathsep=True),
action=opt_help.PrependListAction,
help="One or more directories to search for collections in addition "
"to the default COLLECTIONS_PATHS. Separate multiple paths "
"with '{0}'.".format(os.path.pathsep))
cache_options = opt_help.ArgumentParser(add_help=False)
cache_options.add_argument('--clear-response-cache', dest='clear_response_cache', action='store_true',
default=False, help='Clear the existing server response cache.')
cache_options.add_argument('--no-cache', dest='no_cache', action='store_true', default=False,
help='Do not use the server response cache.')
# Add sub parser for the Galaxy role type (role or collection)
type_parser = self.parser.add_subparsers(metavar='TYPE', dest='type')
type_parser.required = True
# Add sub parser for the Galaxy collection actions
collection = type_parser.add_parser('collection', help='Manage an Ansible Galaxy collection.')
collection.set_defaults(func=self.execute_collection) # to satisfy doc build
collection_parser = collection.add_subparsers(metavar='COLLECTION_ACTION', dest='action')
collection_parser.required = True
self.add_download_options(collection_parser, parents=[common, cache_options])
self.add_init_options(collection_parser, parents=[common, force])
self.add_build_options(collection_parser, parents=[common, force])
self.add_publish_options(collection_parser, parents=[common])
self.add_install_options(collection_parser, parents=[common, force, cache_options])
self.add_list_options(collection_parser, parents=[common, collections_path])
self.add_verify_options(collection_parser, parents=[common, collections_path])
# Add sub parser for the Galaxy role actions
role = type_parser.add_parser('role', help='Manage an Ansible Galaxy role.')
role.set_defaults(func=self.execute_role) # to satisfy doc build
role_parser = role.add_subparsers(metavar='ROLE_ACTION', dest='action')
role_parser.required = True
self.add_init_options(role_parser, parents=[common, force, offline])
self.add_remove_options(role_parser, parents=[common, roles_path])
self.add_delete_options(role_parser, parents=[common, github])
self.add_list_options(role_parser, parents=[common, roles_path])
self.add_search_options(role_parser, parents=[common])
self.add_import_options(role_parser, parents=[common, github])
self.add_setup_options(role_parser, parents=[common, roles_path])
self.add_info_options(role_parser, parents=[common, roles_path, offline])
self.add_install_options(role_parser, parents=[common, force, roles_path])
def add_download_options(self, parser, parents=None):
download_parser = parser.add_parser('download', parents=parents,
help='Download collections and their dependencies as a tarball for an '
'offline install.')
download_parser.set_defaults(func=self.execute_download)
download_parser.add_argument('args', help='Collection(s)', metavar='collection', nargs='*')
download_parser.add_argument('-n', '--no-deps', dest='no_deps', action='store_true', default=False,
help="Don't download collection(s) listed as dependencies.")
download_parser.add_argument('-p', '--download-path', dest='download_path',
default='./collections',
help='The directory to download the collections to.')
download_parser.add_argument('-r', '--requirements-file', dest='requirements',
help='A file containing a list of collections to be downloaded.')
download_parser.add_argument('--pre', dest='allow_pre_release', action='store_true',
help='Include pre-release versions. Semantic versioning pre-releases are ignored by default')
def add_init_options(self, parser, parents=None):
galaxy_type = 'collection' if parser.metavar == 'COLLECTION_ACTION' else 'role'
init_parser = parser.add_parser('init', parents=parents,
help='Initialize new {0} with the base structure of a '
'{0}.'.format(galaxy_type))
init_parser.set_defaults(func=self.execute_init)
init_parser.add_argument('--init-path', dest='init_path', default='./',
help='The path in which the skeleton {0} will be created. The default is the '
'current working directory.'.format(galaxy_type))
init_parser.add_argument('--{0}-skeleton'.format(galaxy_type), dest='{0}_skeleton'.format(galaxy_type),
default=C.GALAXY_COLLECTION_SKELETON if galaxy_type == 'collection' else C.GALAXY_ROLE_SKELETON,
help='The path to a {0} skeleton that the new {0} should be based '
'upon.'.format(galaxy_type))
obj_name_kwargs = {}
if galaxy_type == 'collection':
obj_name_kwargs['type'] = validate_collection_name
init_parser.add_argument('{0}_name'.format(galaxy_type), help='{0} name'.format(galaxy_type.capitalize()),
**obj_name_kwargs)
if galaxy_type == 'role':
init_parser.add_argument('--type', dest='role_type', action='store', default='default',
help="Initialize using an alternate role type. Valid types include: 'container', "
"'apb' and 'network'.")
opt_help.add_runtask_options(init_parser)
def add_remove_options(self, parser, parents=None):
remove_parser = parser.add_parser('remove', parents=parents, help='Delete roles from roles_path.')
remove_parser.set_defaults(func=self.execute_remove)
remove_parser.add_argument('args', help='Role(s)', metavar='role', nargs='+')
def add_delete_options(self, parser, parents=None):
delete_parser = parser.add_parser('delete', parents=parents,
help='Removes the role from Galaxy. It does not remove or alter the actual '
'GitHub repository.')
delete_parser.set_defaults(func=self.execute_delete)
def add_list_options(self, parser, parents=None):
galaxy_type = 'role'
if parser.metavar == 'COLLECTION_ACTION':
galaxy_type = 'collection'
list_parser = parser.add_parser('list', parents=parents,
help='Show the name and version of each {0} installed in the {0}s_path.'.format(galaxy_type))
list_parser.set_defaults(func=self.execute_list)
list_parser.add_argument(galaxy_type, help=galaxy_type.capitalize(), nargs='?', metavar=galaxy_type)
if galaxy_type == 'collection':
list_parser.add_argument('--format', dest='output_format', choices=('human', 'yaml', 'json'), default='human',
help="Format to display the list of collections in.")
def add_search_options(self, parser, parents=None):
search_parser = parser.add_parser('search', parents=parents,
help='Search the Galaxy database by tags, platforms, author and multiple '
'keywords.')
search_parser.set_defaults(func=self.execute_search)
search_parser.add_argument('--platforms', dest='platforms', help='list of OS platforms to filter by')
search_parser.add_argument('--galaxy-tags', dest='galaxy_tags', help='list of galaxy tags to filter by')
search_parser.add_argument('--author', dest='author', help='GitHub username')
search_parser.add_argument('args', help='Search terms', metavar='searchterm', nargs='*')
def add_import_options(self, parser, parents=None):
import_parser = parser.add_parser('import', parents=parents, help='Import a role into a galaxy server')
import_parser.set_defaults(func=self.execute_import)
import_parser.add_argument('--no-wait', dest='wait', action='store_false', default=True,
help="Don't wait for import results.")
import_parser.add_argument('--branch', dest='reference',
help='The name of a branch to import. Defaults to the repository\'s default branch '
'(usually master)')
import_parser.add_argument('--role-name', dest='role_name',
help='The name the role should have, if different than the repo name')
import_parser.add_argument('--status', dest='check_status', action='store_true', default=False,
help='Check the status of the most recent import request for given github_'
'user/github_repo.')
def add_setup_options(self, parser, parents=None):
setup_parser = parser.add_parser('setup', parents=parents,
help='Manage the integration between Galaxy and the given source.')
setup_parser.set_defaults(func=self.execute_setup)
setup_parser.add_argument('--remove', dest='remove_id', default=None,
help='Remove the integration matching the provided ID value. Use --list to see '
'ID values.')
setup_parser.add_argument('--list', dest="setup_list", action='store_true', default=False,
help='List all of your integrations.')
setup_parser.add_argument('source', help='Source')
setup_parser.add_argument('github_user', help='GitHub username')
setup_parser.add_argument('github_repo', help='GitHub repository')
setup_parser.add_argument('secret', help='Secret')
def add_info_options(self, parser, parents=None):
info_parser = parser.add_parser('info', parents=parents, help='View more details about a specific role.')
info_parser.set_defaults(func=self.execute_info)
info_parser.add_argument('args', nargs='+', help='role', metavar='role_name[,version]')
def add_verify_options(self, parser, parents=None):
galaxy_type = 'collection'
verify_parser = parser.add_parser('verify', parents=parents, help='Compare checksums with the collection(s) '
'found on the server and the installed copy. This does not verify dependencies.')
verify_parser.set_defaults(func=self.execute_verify)
verify_parser.add_argument('args', metavar='{0}_name'.format(galaxy_type), nargs='*', help='The installed collection(s) name. '
'This is mutually exclusive with --requirements-file.')
verify_parser.add_argument('-i', '--ignore-errors', dest='ignore_errors', action='store_true', default=False,
help='Ignore errors during verification and continue with the next specified collection.')
verify_parser.add_argument('--offline', dest='offline', action='store_true', default=False,
help='Validate collection integrity locally without contacting server for '
'canonical manifest hash.')
verify_parser.add_argument('-r', '--requirements-file', dest='requirements',
help='A file containing a list of collections to be verified.')
verify_parser.add_argument('--keyring', dest='keyring', default=C.GALAXY_GPG_KEYRING,
help='The keyring used during signature verification') # Eventually default to ~/.ansible/pubring.kbx?
verify_parser.add_argument('--signature', dest='signatures', action='append',
help='An additional signature source to verify the authenticity of the MANIFEST.json before using '
'it to verify the rest of the contents of a collection from a Galaxy server. Use in '
'conjunction with a positional collection name (mutually exclusive with --requirements-file).')
valid_signature_count_help = 'The number of signatures that must successfully verify the collection. This should be a positive integer ' \
'or all to signify that all signatures must be used to verify the collection. ' \
'Prepend the value with + to fail if no valid signatures are found for the collection (e.g. +all).'
ignore_gpg_status_help = 'A space separated list of status codes to ignore during signature verification (for example, NO_PUBKEY FAILURE). ' \
'Descriptions for the choices can be seen at L(https://github.com/gpg/gnupg/blob/master/doc/DETAILS#general-status-codes).' \
'Note: specify these after positional arguments or use -- to separate them.'
verify_parser.add_argument('--required-valid-signature-count', dest='required_valid_signature_count', type=validate_signature_count,
help=valid_signature_count_help, default=C.GALAXY_REQUIRED_VALID_SIGNATURE_COUNT)
verify_parser.add_argument('--ignore-signature-status-code', dest='ignore_gpg_errors', type=str, action='append',
help=opt_help.argparse.SUPPRESS, default=C.GALAXY_IGNORE_INVALID_SIGNATURE_STATUS_CODES,
choices=list(GPG_ERROR_MAP.keys()))
verify_parser.add_argument('--ignore-signature-status-codes', dest='ignore_gpg_errors', type=str, action='extend', nargs='+',
help=ignore_gpg_status_help, default=C.GALAXY_IGNORE_INVALID_SIGNATURE_STATUS_CODES,
choices=list(GPG_ERROR_MAP.keys()))
def add_install_options(self, parser, parents=None):
galaxy_type = 'collection' if parser.metavar == 'COLLECTION_ACTION' else 'role'
args_kwargs = {}
if galaxy_type == 'collection':
args_kwargs['help'] = 'The collection(s) name or path/url to a tar.gz collection artifact. This is ' \
'mutually exclusive with --requirements-file.'
ignore_errors_help = 'Ignore errors during installation and continue with the next specified ' \
'collection. This will not ignore dependency conflict errors.'
else:
args_kwargs['help'] = 'Role name, URL or tar file. This is mutually exclusive with -r.'
ignore_errors_help = 'Ignore errors and continue with the next specified role.'
if self._implicit_role:
# might install both roles and collections
description_text = (
'Install roles and collections from file(s), URL(s) or Ansible '
'Galaxy to the first entry in the config COLLECTIONS_PATH for collections '
'and first entry in the config ROLES_PATH for roles. '
'The first entry in the config ROLES_PATH can be overridden by --roles-path '
'or -p, but this will result in only roles being installed.'
)
prog = 'ansible-galaxy install'
else:
prog = f"ansible-galaxy {galaxy_type} install"
description_text = (
'Install {0}(s) from file(s), URL(s) or Ansible '
'Galaxy to the first entry in the config {1}S_PATH '
'unless overridden by --{0}s-path.'.format(galaxy_type, galaxy_type.upper())
)
install_parser = parser.add_parser('install', parents=parents,
help='Install {0}(s) from file(s), URL(s) or Ansible '
'Galaxy'.format(galaxy_type),
description=description_text,
prog=prog,)
install_parser.set_defaults(func=self.execute_install)
install_parser.add_argument('args', metavar='{0}_name'.format(galaxy_type), nargs='*', **args_kwargs)
install_parser.add_argument('-i', '--ignore-errors', dest='ignore_errors', action='store_true', default=False,
help=ignore_errors_help)
install_exclusive = install_parser.add_mutually_exclusive_group()
install_exclusive.add_argument('-n', '--no-deps', dest='no_deps', action='store_true', default=False,
help="Don't download {0}s listed as dependencies.".format(galaxy_type))
install_exclusive.add_argument('--force-with-deps', dest='force_with_deps', action='store_true', default=False,
help="Force overwriting an existing {0} and its "
"dependencies.".format(galaxy_type))
valid_signature_count_help = 'The number of signatures that must successfully verify the collection. This should be a positive integer ' \
'or -1 to signify that all signatures must be used to verify the collection. ' \
'Prepend the value with + to fail if no valid signatures are found for the collection (e.g. +all).'
ignore_gpg_status_help = 'A space separated list of status codes to ignore during signature verification (for example, NO_PUBKEY FAILURE). ' \
'Descriptions for the choices can be seen at L(https://github.com/gpg/gnupg/blob/master/doc/DETAILS#general-status-codes).' \
'Note: specify these after positional arguments or use -- to separate them.'
if galaxy_type == 'collection':
install_parser.add_argument('-p', '--collections-path', dest='collections_path',
default=self._get_default_collection_path(),
help='The path to the directory containing your collections.')
install_parser.add_argument('-r', '--requirements-file', dest='requirements',
help='A file containing a list of collections to be installed.')
install_parser.add_argument('--pre', dest='allow_pre_release', action='store_true',
help='Include pre-release versions. Semantic versioning pre-releases are ignored by default')
install_parser.add_argument('-U', '--upgrade', dest='upgrade', action='store_true', default=False,
help='Upgrade installed collection artifacts. This will also update dependencies unless --no-deps is provided')
install_parser.add_argument('--keyring', dest='keyring', default=C.GALAXY_GPG_KEYRING,
help='The keyring used during signature verification') # Eventually default to ~/.ansible/pubring.kbx?
install_parser.add_argument('--disable-gpg-verify', dest='disable_gpg_verify', action='store_true',
default=C.GALAXY_DISABLE_GPG_VERIFY,
help='Disable GPG signature verification when installing collections from a Galaxy server')
install_parser.add_argument('--signature', dest='signatures', action='append',
help='An additional signature source to verify the authenticity of the MANIFEST.json before '
'installing the collection from a Galaxy server. Use in conjunction with a positional '
'collection name (mutually exclusive with --requirements-file).')
install_parser.add_argument('--required-valid-signature-count', dest='required_valid_signature_count', type=validate_signature_count,
help=valid_signature_count_help, default=C.GALAXY_REQUIRED_VALID_SIGNATURE_COUNT)
install_parser.add_argument('--ignore-signature-status-code', dest='ignore_gpg_errors', type=str, action='append',
help=opt_help.argparse.SUPPRESS, default=C.GALAXY_IGNORE_INVALID_SIGNATURE_STATUS_CODES,
choices=list(GPG_ERROR_MAP.keys()))
install_parser.add_argument('--ignore-signature-status-codes', dest='ignore_gpg_errors', type=str, action='extend', nargs='+',
help=ignore_gpg_status_help, default=C.GALAXY_IGNORE_INVALID_SIGNATURE_STATUS_CODES,
choices=list(GPG_ERROR_MAP.keys()))
install_parser.add_argument('--offline', dest='offline', action='store_true', default=False,
help='Install collection artifacts (tarballs) without contacting any distribution servers. '
'This does not apply to collections in remote Git repositories or URLs to remote tarballs.'
)
else:
if self._implicit_role:
install_parser.add_argument('-r', '--role-file', dest='requirements',
help='A file containing a list of collections and roles to be installed.')
else:
install_parser.add_argument('-r', '--role-file', dest='requirements',
help='A file containing a list of roles to be installed.')
r_re = re.compile(r'^(?", v)
v = const_pattern.sub(r"'\1'", v)
return textwrap.fill(v, width=117, initial_indent="# ", subsequent_indent="# ", break_on_hyphens=False)
loader = DataLoader()
templar = TemplateEngine(loader, variables={'required_config': required_config, 'optional_config': optional_config})
templar.environment.filters['comment_ify'] = comment_ify
meta_value = templar.template(meta_template)
return meta_value
def _require_one_of_collections_requirements(
self, collections, requirements_file,
signatures=None,
artifacts_manager=None,
):
if collections and requirements_file:
raise AnsibleError("The positional collection_name arg and --requirements-file are mutually exclusive.")
elif not collections and not requirements_file:
raise AnsibleError("You must specify a collection name or a requirements file.")
elif requirements_file:
if signatures is not None:
raise AnsibleError(
"The --signatures option and --requirements-file are mutually exclusive. "
"Use the --signatures with positional collection_name args or provide a "
"'signatures' key for requirements in the --requirements-file."
)
requirements_file = GalaxyCLI._resolve_path(requirements_file)
requirements = self._parse_requirements_file(
requirements_file,
allow_old_format=False,
artifacts_manager=artifacts_manager,
)
else:
requirements = {
'collections': [
Requirement.from_string(coll_input, artifacts_manager, signatures)
for coll_input in collections
],
'roles': [],
}
return requirements
############################
# execute actions
############################
def execute_role(self):
"""
Perform the action on an Ansible Galaxy role. Must be combined with a further action like delete/install/init
as listed below.
"""
# To satisfy doc build
pass
def execute_collection(self):
"""
Perform the action on an Ansible Galaxy collection. Must be combined with a further action like init/install as
listed below.
"""
# To satisfy doc build
pass
def execute_build(self):
"""
Build an Ansible Galaxy collection artifact that can be stored in a central repository like Ansible Galaxy.
By default, this command builds from the current working directory. You can optionally pass in the
collection input path (where the ``galaxy.yml`` file is).
"""
force = context.CLIARGS['force']
output_path = GalaxyCLI._resolve_path(context.CLIARGS['output_path'])
b_output_path = to_bytes(output_path, errors='surrogate_or_strict')
if not os.path.exists(b_output_path):
os.makedirs(b_output_path)
elif os.path.isfile(b_output_path):
raise AnsibleError("- the output collection directory %s is a file - aborting" % to_native(output_path))
for collection_path in context.CLIARGS['args']:
collection_path = GalaxyCLI._resolve_path(collection_path)
build_collection(
to_text(collection_path, errors='surrogate_or_strict'),
to_text(output_path, errors='surrogate_or_strict'),
force,
)
@with_collection_artifacts_manager
def execute_download(self, artifacts_manager=None):
"""Download collections and their dependencies as a tarball for an offline install."""
collections = context.CLIARGS['args']
no_deps = context.CLIARGS['no_deps']
download_path = context.CLIARGS['download_path']
requirements_file = context.CLIARGS['requirements']
if requirements_file:
requirements_file = GalaxyCLI._resolve_path(requirements_file)
requirements = self._require_one_of_collections_requirements(
collections, requirements_file,
artifacts_manager=artifacts_manager,
)['collections']
download_path = GalaxyCLI._resolve_path(download_path)
b_download_path = to_bytes(download_path, errors='surrogate_or_strict')
if not os.path.exists(b_download_path):
os.makedirs(b_download_path)
download_collections(
requirements, download_path, self.api_servers, no_deps,
context.CLIARGS['allow_pre_release'],
artifacts_manager=artifacts_manager,
)
return 0
def execute_init(self):
"""
Creates the skeleton framework of a role or collection that complies with the Galaxy metadata format.
Requires a role or collection name. The collection name must be in the format ``.``.
"""
galaxy_type = context.CLIARGS['type']
init_path = context.CLIARGS['init_path']
force = context.CLIARGS['force']
obj_skeleton = context.CLIARGS['{0}_skeleton'.format(galaxy_type)]
obj_name = context.CLIARGS['{0}_name'.format(galaxy_type)]
inject_data = dict(
description='your {0} description'.format(galaxy_type),
ansible_plugin_list_dir=get_versioned_doclink('plugins/plugins.html'),
)
if galaxy_type == 'role':
inject_data.update(dict(
author='your name',
company='your company (optional)',
license='license (GPL-2.0-or-later, MIT, etc)',
role_name=obj_name,
role_type=context.CLIARGS['role_type'],
issue_tracker_url='http://example.com/issue/tracker',
repository_url='http://example.com/repository',
documentation_url='http://docs.example.com',
homepage_url='http://example.com',
min_ansible_version=ansible_version[:3], # x.y
dependencies=[],
))
skeleton_ignore_expressions = C.GALAXY_ROLE_SKELETON_IGNORE
obj_path = os.path.join(init_path, obj_name)
elif galaxy_type == 'collection':
namespace, collection_name = obj_name.split('.', 1)
inject_data.update(dict(
namespace=namespace,
collection_name=collection_name,
version='1.0.0',
readme='README.md',
authors=['your name '],
license=['GPL-2.0-or-later'],
repository='http://example.com/repository',
documentation='http://docs.example.com',
homepage='http://example.com',
issues='http://example.com/issue/tracker',
build_ignore=[],
))
skeleton_ignore_expressions = C.GALAXY_COLLECTION_SKELETON_IGNORE
obj_path = os.path.join(init_path, namespace, collection_name)
b_obj_path = to_bytes(obj_path, errors='surrogate_or_strict')
if os.path.exists(b_obj_path):
if os.path.isfile(obj_path):
raise AnsibleError("- the path %s already exists, but is a file - aborting" % to_native(obj_path))
elif not force:
raise AnsibleError("- the directory %s already exists. "
"You can use --force to re-initialize this directory,\n"
"however it will reset any main.yml files that may have\n"
"been modified there already." % to_native(obj_path))
# delete the contents rather than the collection root in case init was run from the root (--init-path ../../)
for root, dirs, files in os.walk(b_obj_path, topdown=True):
for old_dir in dirs:
path = os.path.join(root, old_dir)
shutil.rmtree(path)
for old_file in files:
path = os.path.join(root, old_file)
os.unlink(path)
if obj_skeleton is not None:
own_skeleton = False
else:
own_skeleton = True
obj_skeleton = self.galaxy.default_role_skeleton_path
skeleton_ignore_expressions = ['^.*/.git_keep$']
obj_skeleton = os.path.expanduser(obj_skeleton)
skeleton_ignore_re = [re.compile(x) for x in skeleton_ignore_expressions]
if not os.path.exists(obj_skeleton):
raise AnsibleError("- the skeleton path '{0}' does not exist, cannot init {1}".format(
to_native(obj_skeleton), galaxy_type)
)
loader = DataLoader()
inject_data.update(load_extra_vars(loader))
templar = TemplateEngine(loader, variables=inject_data)
# create role directory
if not os.path.exists(b_obj_path):
os.makedirs(b_obj_path)
for root, dirs, files in os.walk(obj_skeleton, topdown=True):
rel_root = os.path.relpath(root, obj_skeleton)
rel_dirs = rel_root.split(os.sep)
rel_root_dir = rel_dirs[0]
if galaxy_type == 'collection':
# A collection can contain templates in playbooks/*/templates and roles/*/templates
in_templates_dir = rel_root_dir in ['playbooks', 'roles'] and 'templates' in rel_dirs
else:
in_templates_dir = rel_root_dir == 'templates'
# Filter out ignored directory names
# Use [:] to mutate the list os.walk uses
dirs[:] = [d for d in dirs if not any(r.match(d) for r in skeleton_ignore_re)]
for f in files:
filename, ext = os.path.splitext(f)
if any(r.match(os.path.join(rel_root, f)) for r in skeleton_ignore_re):
continue
if galaxy_type == 'collection' and own_skeleton and rel_root == '.' and f == 'galaxy.yml.j2':
# Special use case for galaxy.yml.j2 in our own default collection skeleton. We build the options
# dynamically which requires special options to be set.
# The templated data's keys must match the key name but the inject data contains collection_name
# instead of name. We just make a copy and change the key back to name for this file.
template_data = inject_data.copy()
template_data['name'] = template_data.pop('collection_name')
meta_value = GalaxyCLI._get_skeleton_galaxy_yml(os.path.join(root, rel_root, f), template_data)
b_dest_file = to_bytes(os.path.join(obj_path, rel_root, filename), errors='surrogate_or_strict')
with open(b_dest_file, 'wb') as galaxy_obj:
galaxy_obj.write(to_bytes(meta_value, errors='surrogate_or_strict'))
elif ext == ".j2" and not in_templates_dir:
src_template = os.path.join(root, f)
dest_file = os.path.join(obj_path, rel_root, filename)
template_data = trust_as_template(loader.get_text_file_contents(src_template))
try:
b_rendered = to_bytes(templar.template(template_data), errors='surrogate_or_strict')
except AnsibleError as e:
shutil.rmtree(b_obj_path)
raise AnsibleError(f"Failed to create {galaxy_type.title()} {obj_name}. Templating {src_template} failed with the error: {e}") from e
with open(dest_file, 'wb') as df:
df.write(b_rendered)
else:
f_rel_path = os.path.relpath(os.path.join(root, f), obj_skeleton)
shutil.copyfile(os.path.join(root, f), os.path.join(obj_path, f_rel_path), follow_symlinks=False)
for d in dirs:
b_dir_path = to_bytes(os.path.join(obj_path, rel_root, d), errors='surrogate_or_strict')
if os.path.exists(b_dir_path):
continue
b_src_dir = to_bytes(os.path.join(root, d), errors='surrogate_or_strict')
if os.path.islink(b_src_dir):
shutil.copyfile(b_src_dir, b_dir_path, follow_symlinks=False)
else:
os.makedirs(b_dir_path)
display.display("- %s %s was created successfully" % (galaxy_type.title(), obj_name))
def execute_info(self):
"""
prints out detailed information about an installed role as well as info available from the galaxy API.
"""
roles_path = context.CLIARGS['roles_path']
data = ''
for role in context.CLIARGS['args']:
role_info = {'path': roles_path}
gr = GalaxyRole(self.galaxy, self.lazy_role_api, role)
install_info = gr.install_info
if install_info:
if 'version' in install_info:
install_info['installed_version'] = install_info['version']
del install_info['version']
role_info.update(install_info)
if not context.CLIARGS['offline']:
remote_data = None
try:
remote_data = self.api.lookup_role_by_name(role, False)
except GalaxyError as e:
if e.http_code == 400 and 'Bad Request' in e.message:
# Role does not exist in Ansible Galaxy
data = u"- the role %s was not found" % role
break
raise AnsibleError("Unable to find info about '%s': %s" % (role, e))
if remote_data:
role_info.update(remote_data)
else:
data = u"- the role %s was not found" % role
break
elif context.CLIARGS['offline'] and not gr._exists:
data = u"- the role %s was not found" % role
break
if gr.metadata:
role_info.update(gr.metadata)
req = RoleRequirement()
role_spec = req.role_yaml_parse({'role': role})
if role_spec:
role_info.update(role_spec)
data += self._display_role_info(role_info)
self.pager(data)
@with_collection_artifacts_manager
def execute_verify(self, artifacts_manager=None):
"""Compare checksums with the collection(s) found on the server and the installed copy. This does not verify dependencies."""
collections = context.CLIARGS['args']
search_paths = AnsibleCollectionConfig.collection_paths
ignore_errors = context.CLIARGS['ignore_errors']
local_verify_only = context.CLIARGS['offline']
requirements_file = context.CLIARGS['requirements']
signatures = context.CLIARGS['signatures']
if signatures is not None:
signatures = list(signatures)
requirements = self._require_one_of_collections_requirements(
collections, requirements_file,
signatures=signatures,
artifacts_manager=artifacts_manager,
)['collections']
resolved_paths = [validate_collection_path(GalaxyCLI._resolve_path(path)) for path in search_paths]
results = verify_collections(
requirements, resolved_paths,
self.api_servers, ignore_errors,
local_verify_only=local_verify_only,
artifacts_manager=artifacts_manager,
)
if any(result for result in results if not result.success):
return 1
return 0
@with_collection_artifacts_manager
def execute_install(self, artifacts_manager=None):
"""
Install one or more roles(``ansible-galaxy role install``), or one or more collections(``ansible-galaxy collection install``).
You can pass in a list (roles or collections) or use the file
option listed below (these are mutually exclusive). If you pass in a list, it
can be a name (which will be downloaded via the galaxy API and github), or it can be a local tar archive file.
"""
install_items = context.CLIARGS['args']
requirements_file = context.CLIARGS['requirements']
collection_path = None
signatures = context.CLIARGS.get('signatures')
if signatures is not None:
signatures = list(signatures)
if requirements_file:
requirements_file = GalaxyCLI._resolve_path(requirements_file)
two_type_warning = "The requirements file '%s' contains {0}s which will be ignored. To install these {0}s " \
"run 'ansible-galaxy {0} install -r' or to install both at the same time run " \
"'ansible-galaxy install -r' without a custom install path." % to_text(requirements_file)
# TODO: Would be nice to share the same behaviour with args and -r in collections and roles.
collection_requirements = []
role_requirements = []
if context.CLIARGS['type'] == 'collection':
collection_path = GalaxyCLI._resolve_path(context.CLIARGS['collections_path'])
requirements = self._require_one_of_collections_requirements(
install_items, requirements_file,
signatures=signatures,
artifacts_manager=artifacts_manager,
)
collection_requirements = requirements['collections']
if requirements['roles']:
display.vvv(two_type_warning.format('role'))
else:
if not install_items and requirements_file is None:
raise AnsibleOptionsError("- you must specify a user/role name or a roles file")
if requirements_file:
if not (requirements_file.endswith('.yaml') or requirements_file.endswith('.yml')):
raise AnsibleError("Invalid role requirements file, it must end with a .yml or .yaml extension")
galaxy_args = self._raw_args
will_install_collections = self._implicit_role and '-p' not in galaxy_args and '--roles-path' not in galaxy_args
requirements = self._parse_requirements_file(
requirements_file,
artifacts_manager=artifacts_manager,
validate_signature_options=will_install_collections,
)
role_requirements = requirements['roles']
# We can only install collections and roles at the same time if the type wasn't specified and the -p
# argument was not used. If collections are present in the requirements then at least display a msg.
if requirements['collections'] and (not self._implicit_role or '-p' in galaxy_args or
'--roles-path' in galaxy_args):
# We only want to display a warning if 'ansible-galaxy install -r ... -p ...'. Other cases the user
# was explicit about the type and shouldn't care that collections were skipped.
display_func = display.warning if self._implicit_role else display.vvv
display_func(two_type_warning.format('collection'))
else:
collection_path = self._get_default_collection_path()
collection_requirements = requirements['collections']
else:
# roles were specified directly, so we'll just go out grab them
# (and their dependencies, unless the user doesn't want us to).
for rname in context.CLIARGS['args']:
role = RoleRequirement.role_yaml_parse(rname.strip())
role_requirements.append(GalaxyRole(self.galaxy, self.lazy_role_api, **role))
if not role_requirements and not collection_requirements:
display.display("Skipping install, no requirements found")
return
if role_requirements:
display.display("Starting galaxy role install process")
self._execute_install_role(role_requirements)
if collection_requirements:
display.display("Starting galaxy collection install process")
# Collections can technically be installed even when ansible-galaxy is in role mode so we need to pass in
# the install path as context.CLIARGS['collections_path'] won't be set (default is calculated above).
self._execute_install_collection(
collection_requirements, collection_path,
artifacts_manager=artifacts_manager,
)
def _execute_install_collection(
self, requirements, path, artifacts_manager,
):
force = context.CLIARGS['force']
ignore_errors = context.CLIARGS['ignore_errors']
no_deps = context.CLIARGS['no_deps']
force_with_deps = context.CLIARGS['force_with_deps']
try:
disable_gpg_verify = context.CLIARGS['disable_gpg_verify']
except KeyError:
if self._implicit_role:
raise AnsibleError(
'Unable to properly parse command line arguments. Please use "ansible-galaxy collection install" '
'instead of "ansible-galaxy install".'
)
raise
# If `ansible-galaxy install` is used, collection-only options aren't available to the user and won't be in context.CLIARGS
allow_pre_release = context.CLIARGS.get('allow_pre_release', False)
upgrade = context.CLIARGS.get('upgrade', False)
collections_path = C.COLLECTIONS_PATHS
managed_paths = set(validate_collection_path(p) for p in C.COLLECTIONS_PATHS)
read_req_paths = set(validate_collection_path(p) for p in AnsibleCollectionConfig.collection_paths)
unexpected_path = C.GALAXY_COLLECTIONS_PATH_WARNING and not any(p.startswith(path) for p in managed_paths)
if unexpected_path and any(p.startswith(path) for p in read_req_paths):
display.warning(
f"The specified collections path '{path}' appears to be part of the pip Ansible package. "
"Managing these directly with ansible-galaxy could break the Ansible package. "
"Install collections to a configured collections path, which will take precedence over "
"collections found in the PYTHONPATH."
)
elif unexpected_path:
display.warning("The specified collections path '%s' is not part of the configured Ansible "
"collections paths '%s'. The installed collection will not be picked up in an Ansible "
"run, unless within a playbook-adjacent collections directory." % (to_text(path), to_text(":".join(collections_path))))
output_path = validate_collection_path(path)
b_output_path = to_bytes(output_path, errors='surrogate_or_strict')
if not os.path.exists(b_output_path):
os.makedirs(b_output_path)
install_collections(
requirements, output_path, self.api_servers, ignore_errors,
no_deps, force, force_with_deps, upgrade,
allow_pre_release=allow_pre_release,
artifacts_manager=artifacts_manager,
disable_gpg_verify=disable_gpg_verify,
offline=context.CLIARGS.get('offline', False),
read_requirement_paths=read_req_paths,
)
return 0
def _execute_install_role(self, requirements):
role_file = context.CLIARGS['requirements']
no_deps = context.CLIARGS['no_deps']
force_deps = context.CLIARGS['force_with_deps']
force = context.CLIARGS['force'] or force_deps
for role in requirements:
# only process roles in roles files when names matches if given
if role_file and context.CLIARGS['args'] and role.name not in context.CLIARGS['args']:
display.vvv('Skipping role %s' % role.name)
continue
display.vvv('Processing role %s ' % role.name)
# query the galaxy API for the role data
if role.install_info is not None:
if role.install_info['version'] != role.version or force:
if force:
display.display('- changing role %s from %s to %s' %
(role.name, role.install_info['version'], role.version or "unspecified"))
role.remove()
else:
display.warning('- %s (%s) is already installed - use --force to change version to %s' %
(role.name, role.install_info['version'], role.version or "unspecified"))
continue
else:
if not force:
display.display('- %s is already installed, skipping.' % str(role))
continue
try:
installed = role.install()
except AnsibleError as e:
display.warning(u"- %s was NOT installed successfully: %s " % (role.name, to_text(e)))
self.exit_without_ignore()
continue
# install dependencies, if we want them
if not no_deps and installed:
if not role.metadata:
# NOTE: the meta file is also required for installing the role, not just dependencies
display.warning("Meta file %s is empty. Skipping dependencies." % role.path)
else:
role_dependencies = role.metadata_dependencies + role.requirements
for dep in role_dependencies:
display.debug('Installing dep %s' % dep)
dep_req = RoleRequirement()
dep_info = dep_req.role_yaml_parse(dep)
dep_role = GalaxyRole(self.galaxy, self.lazy_role_api, **dep_info)
if '.' not in dep_role.name and '.' not in dep_role.src and dep_role.scm is None:
# we know we can skip this, as it's not going to
# be found on galaxy.ansible.com
continue
if dep_role.install_info is None:
if dep_role not in requirements:
display.display('- adding dependency: %s' % to_text(dep_role))
requirements.append(dep_role)
else:
display.display('- dependency %s already pending installation.' % dep_role.name)
else:
if dep_role.install_info['version'] != dep_role.version:
if force_deps:
display.display('- changing dependent role %s from %s to %s' %
(dep_role.name, dep_role.install_info['version'], dep_role.version or "unspecified"))
dep_role.remove()
requirements.append(dep_role)
else:
display.warning('- dependency %s (%s) from role %s differs from already installed version (%s), skipping' %
(to_text(dep_role), dep_role.version, role.name, dep_role.install_info['version']))
else:
if force_deps:
requirements.append(dep_role)
else:
display.display('- dependency %s is already installed, skipping.' % dep_role.name)
if not installed:
display.warning("- %s was NOT installed successfully." % role.name)
self.exit_without_ignore()
return 0
def execute_remove(self):
"""
removes the list of roles passed as arguments from the local system.
"""
if not context.CLIARGS['args']:
raise AnsibleOptionsError('- you must specify at least one role to remove.')
for role_name in context.CLIARGS['args']:
role = GalaxyRole(self.galaxy, self.api, role_name)
try:
if role.remove():
display.display('- successfully removed %s' % role_name)
else:
display.display('- %s is not installed, skipping.' % role_name)
except Exception as e:
raise AnsibleError("Failed to remove role %s: %s" % (role_name, to_native(e)))
return 0
def execute_list(self):
"""
List installed collections or roles
"""
if context.CLIARGS['type'] == 'role':
self.execute_list_role()
elif context.CLIARGS['type'] == 'collection':
self.execute_list_collection()
def execute_list_role(self):
"""
List all roles installed on the local system or a specific role
"""
path_found = False
role_found = False
warnings = []
roles_search_paths = context.CLIARGS['roles_path']
role_name = context.CLIARGS['role']
for path in roles_search_paths:
role_path = GalaxyCLI._resolve_path(path)
if os.path.isdir(path):
path_found = True
else:
warnings.append("- the configured path {0} does not exist.".format(path))
continue
if role_name:
# show the requested role, if it exists
gr = GalaxyRole(self.galaxy, self.lazy_role_api, role_name, path=os.path.join(role_path, role_name))
if os.path.isdir(gr.path):
role_found = True
display.display('# %s' % os.path.dirname(gr.path))
_display_role(gr)
break
warnings.append("- the role %s was not found" % role_name)
else:
if not os.path.exists(role_path):
warnings.append("- the configured path %s does not exist." % role_path)
continue
if not os.path.isdir(role_path):
warnings.append("- the configured path %s, exists, but it is not a directory." % role_path)
continue
display.display('# %s' % role_path)
path_files = os.listdir(role_path)
for path_file in path_files:
gr = GalaxyRole(self.galaxy, self.lazy_role_api, path_file, path=path)
if gr.metadata:
_display_role(gr)
# Do not warn if the role was found in any of the search paths
if role_found and role_name:
warnings = []
for w in warnings:
display.warning(w)
if not path_found:
raise AnsibleOptionsError(
"- None of the provided paths were usable. Please specify a valid path with --{0}s-path".format(context.CLIARGS['type'])
)
return 0
@with_collection_artifacts_manager
def execute_list_collection(self, artifacts_manager=None):
"""
List all collections installed on the local system
:param artifacts_manager: Artifacts manager.
"""
if artifacts_manager is not None:
artifacts_manager.require_build_metadata = False
output_format = context.CLIARGS['output_format']
collection_name = context.CLIARGS['collection']
default_collections_path = set(C.COLLECTIONS_PATHS)
collections_search_paths = (
set(context.CLIARGS['collections_path'] or []) | default_collections_path | set(AnsibleCollectionConfig.collection_paths)
)
collections_in_paths = {}
warnings = []
path_found = False
collection_found = False
namespace_filter = None
collection_filter = None
if collection_name:
# list a specific collection
validate_collection_name(collection_name)
namespace_filter, collection_filter = collection_name.split('.')
collections = list(find_existing_collections(
list(collections_search_paths),
artifacts_manager,
namespace_filter=namespace_filter,
collection_filter=collection_filter,
dedupe=False
))
seen = set()
fqcn_width, version_width = _get_collection_widths(collections)
for collection in sorted(collections, key=lambda c: c.src):
collection_found = True
collection_path = pathlib.Path(to_text(collection.src)).parent.parent.as_posix()
if output_format in {'yaml', 'json'}:
collections_in_paths.setdefault(collection_path, {})
collections_in_paths[collection_path][collection.fqcn] = {'version': collection.ver}
else:
if collection_path not in seen:
_display_header(
collection_path,
'Collection',
'Version',
fqcn_width,
version_width
)
seen.add(collection_path)
_display_collection(collection, fqcn_width, version_width)
path_found = False
for path in collections_search_paths:
if not os.path.exists(path):
if path in default_collections_path:
# don't warn for missing default paths
continue
warnings.append("- the configured path {0} does not exist.".format(path))
elif os.path.exists(path) and not os.path.isdir(path):
warnings.append("- the configured path {0}, exists, but it is not a directory.".format(path))
else:
path_found = True
# Do not warn if the specific collection was found in any of the search paths
if collection_found and collection_name:
warnings = []
for w in warnings:
display.warning(w)
if not collections and not path_found:
raise AnsibleOptionsError(
"- None of the provided paths were usable. Please specify a valid path with --{0}s-path".format(context.CLIARGS['type'])
)
if output_format == 'json':
display.display(json.dumps(collections_in_paths))
elif output_format == 'yaml':
display.display(yaml_dump(collections_in_paths))
return 0
def execute_publish(self):
"""
Publish a collection into Ansible Galaxy. Requires the path to the collection tarball to publish.
"""
collection_path = GalaxyCLI._resolve_path(context.CLIARGS['args'])
wait = context.CLIARGS['wait']
timeout = context.CLIARGS['import_timeout']
publish_collection(collection_path, self.api, wait, timeout)
def execute_search(self):
""" searches for roles on the Ansible Galaxy server"""
page_size = 1000
search = None
if context.CLIARGS['args']:
search = '+'.join(context.CLIARGS['args'])
if not search and not context.CLIARGS['platforms'] and not context.CLIARGS['galaxy_tags'] and not context.CLIARGS['author']:
raise AnsibleError("Invalid query. At least one search term, platform, galaxy tag or author must be provided.")
response = self.api.search_roles(search, platforms=context.CLIARGS['platforms'],
tags=context.CLIARGS['galaxy_tags'], author=context.CLIARGS['author'], page_size=page_size)
if response['count'] == 0:
display.warning("No roles match your search.")
return 0
data = [u'']
if response['count'] > page_size:
data.append(u"Found %d roles matching your search. Showing first %s." % (response['count'], page_size))
else:
data.append(u"Found %d roles matching your search:" % response['count'])
max_len = []
for role in response['results']:
max_len.append(len(role['username'] + '.' + role['name']))
name_len = max(max_len)
format_str = u" %%-%ds %%s" % name_len
data.append(u'')
data.append(format_str % (u"Name", u"Description"))
data.append(format_str % (u"----", u"-----------"))
for role in response['results']:
data.append(format_str % (u'%s.%s' % (role['username'], role['name']), role['description']))
data = u'\n'.join(data)
self.pager(data)
return 0
_task_check_delay_sec = 10 # allows unit test override
def execute_import(self):
""" used to import a role into Ansible Galaxy """
colors = {
'INFO': 'normal',
'WARNING': C.COLOR_WARN,
'ERROR': C.COLOR_ERROR,
'SUCCESS': C.COLOR_OK,
'FAILED': C.COLOR_ERROR,
}
github_user = to_text(context.CLIARGS['github_user'], errors='surrogate_or_strict')
github_repo = to_text(context.CLIARGS['github_repo'], errors='surrogate_or_strict')
rc = 0
if context.CLIARGS['check_status']:
task = self.api.get_import_task(github_user=github_user, github_repo=github_repo)
else:
# Submit an import request
task = self.api.create_import_task(github_user, github_repo,
reference=context.CLIARGS['reference'],
role_name=context.CLIARGS['role_name'])
if len(task) > 1:
# found multiple roles associated with github_user/github_repo
display.display("WARNING: More than one Galaxy role associated with Github repo %s/%s." % (github_user, github_repo),
color='yellow')
display.display("The following Galaxy roles are being updated:" + u'\n', color=C.COLOR_CHANGED)
for t in task:
display.display('%s.%s' % (t['summary_fields']['role']['namespace'], t['summary_fields']['role']['name']), color=C.COLOR_CHANGED)
display.display(u'\nTo properly namespace this role, remove each of the above and re-import %s/%s from scratch' % (github_user, github_repo),
color=C.COLOR_CHANGED)
return rc
# found a single role as expected
display.display("Successfully submitted import request %d" % task[0]['id'])
if not context.CLIARGS['wait']:
display.display("Role name: %s" % task[0]['summary_fields']['role']['name'])
display.display("Repo: %s/%s" % (task[0]['github_user'], task[0]['github_repo']))
if context.CLIARGS['check_status'] or context.CLIARGS['wait']:
# Get the status of the import
msg_list = []
finished = False
while not finished:
task = self.api.get_import_task(task_id=task[0]['id'])
for msg in task[0]['summary_fields']['task_messages']:
if msg['id'] not in msg_list:
display.display(msg['message_text'], color=colors[msg['message_type']])
msg_list.append(msg['id'])
if (state := task[0]['state']) in ['SUCCESS', 'FAILED']:
rc = ['SUCCESS', 'FAILED'].index(state)
finished = True
else:
time.sleep(self._task_check_delay_sec)
return rc
def execute_setup(self):
""" Setup an integration from Github or Travis for Ansible Galaxy roles"""
if context.CLIARGS['setup_list']:
# List existing integration secrets
secrets = self.api.list_secrets()
if len(secrets) == 0:
# None found
display.display("No integrations found.")
return 0
display.display(u'\n' + "ID Source Repo", color=C.COLOR_OK)
display.display("---------- ---------- ----------", color=C.COLOR_OK)
for secret in secrets:
display.display("%-10s %-10s %s/%s" % (secret['id'], secret['source'], secret['github_user'],
secret['github_repo']), color=C.COLOR_OK)
return 0
if context.CLIARGS['remove_id']:
# Remove a secret
self.api.remove_secret(context.CLIARGS['remove_id'])
display.display("Secret removed. Integrations using this secret will not longer work.", color=C.COLOR_OK)
return 0
source = context.CLIARGS['source']
github_user = context.CLIARGS['github_user']
github_repo = context.CLIARGS['github_repo']
secret = context.CLIARGS['secret']
resp = self.api.add_secret(source, github_user, github_repo, secret)
display.display("Added integration for %s %s/%s" % (resp['source'], resp['github_user'], resp['github_repo']))
return 0
def execute_delete(self):
""" Delete a role from Ansible Galaxy. """
github_user = context.CLIARGS['github_user']
github_repo = context.CLIARGS['github_repo']
resp = self.api.delete_role(github_user, github_repo)
if len(resp['deleted_roles']) > 1:
display.display("Deleted the following roles:")
display.display("ID User Name")
display.display("------ --------------- ----------")
for role in resp['deleted_roles']:
display.display("%-8s %-15s %s" % (role.id, role.namespace, role.name))
display.display(resp['status'])
return 0
def main(args=None):
GalaxyCLI.cli_executor(args)
if __name__ == '__main__':
main()
ansible_core-2.19.0b4/lib/ansible/cli/inventory.py 0000755 0000000 0000000 00000037645 15010426755 020604 0 ustar 00root root #!/usr/bin/env python
# Copyright: (c) 2017, Brian Coca
# Copyright: (c) 2018, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# PYTHON_ARGCOMPLETE_OK
from __future__ import annotations
# ansible.cli needs to be imported first, to ensure the source bin/* scripts run that code first
from ansible.cli import CLI
import json
import sys
import typing as t
import argparse
import functools
from ansible import constants as C
from ansible import context
from ansible.cli.arguments import option_helpers as opt_help
from ansible.errors import AnsibleError, AnsibleOptionsError, AnsibleRuntimeError
from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text
from ansible._internal._json._profiles import _inventory_legacy
from ansible.utils.vars import combine_vars
from ansible.utils.display import Display
from ansible.vars.plugins import get_vars_from_inventory_sources, get_vars_from_path
display = Display()
class InventoryCLI(CLI):
""" used to display or dump the configured inventory as Ansible sees it """
name = 'ansible-inventory'
ARGUMENTS = {'group': 'The name of a group in the inventory, relevant when using --graph', }
def __init__(self, args):
super(InventoryCLI, self).__init__(args)
self.vm = None
self.loader = None
self.inventory = None
def init_parser(self):
super(InventoryCLI, self).init_parser(
usage='usage: %prog [options] [group]',
desc='Show Ansible inventory information, by default it uses the inventory script JSON format')
opt_help.add_inventory_options(self.parser)
opt_help.add_vault_options(self.parser)
opt_help.add_basedir_options(self.parser)
opt_help.add_runtask_options(self.parser)
# remove unused default options
self.parser.add_argument('--list-hosts', help=argparse.SUPPRESS, action=opt_help.UnrecognizedArgument)
self.parser.add_argument('args', metavar='group', nargs='?', help='The name of a group in the inventory, relevant when using --graph')
# Actions
action_group = self.parser.add_argument_group("Actions", "One of following must be used on invocation, ONLY ONE!")
action_group.add_argument("--list", action="store_true", default=False, dest='list', help='Output all hosts info, works as inventory script')
action_group.add_argument("--host", action="store", default=None, dest='host',
help='Output specific host info, works as inventory script. It will ignore limit')
action_group.add_argument("--graph", action="store_true", default=False, dest='graph',
help='create inventory graph, if supplying pattern it must be a valid group name. It will ignore limit')
self.parser.add_argument_group(action_group)
# graph
self.parser.add_argument("-y", "--yaml", action="store_true", default=False, dest='yaml',
help='Use YAML format instead of default JSON, ignored for --graph')
self.parser.add_argument('--toml', action='store_true', default=False, dest='toml',
help='Use TOML format instead of default JSON, ignored for --graph')
self.parser.add_argument("--vars", action="store_true", default=False, dest='show_vars',
help='Add vars to graph display, ignored unless used with --graph')
# list
self.parser.add_argument("--export", action="store_true", default=C.INVENTORY_EXPORT, dest='export',
help="When doing --list, represent in a way that is optimized for export,"
"not as an accurate representation of how Ansible has processed it")
self.parser.add_argument('--output', default=None, dest='output_file',
help="When doing --list, send the inventory to a file instead of to the screen")
# self.parser.add_argument("--ignore-vars-plugins", action="store_true", default=False, dest='ignore_vars_plugins',
# help="When doing --list, skip vars data from vars plugins, by default, this would include group_vars/ and host_vars/")
def post_process_args(self, options):
options = super(InventoryCLI, self).post_process_args(options)
display.verbosity = options.verbosity
self.validate_conflicts(options)
# there can be only one! and, at least, one!
used = 0
for opt in (options.list, options.host, options.graph):
if opt:
used += 1
if used == 0:
raise AnsibleOptionsError("No action selected, at least one of --host, --graph or --list needs to be specified.")
elif used > 1:
raise AnsibleOptionsError("Conflicting options used, only one of --host, --graph or --list can be used at the same time.")
# set host pattern to default if not supplied
if options.args:
options.pattern = options.args
else:
options.pattern = 'all'
return options
def run(self):
super(InventoryCLI, self).run()
# Initialize needed objects
self.loader, self.inventory, self.vm = self._play_prereqs()
results = None
if context.CLIARGS['host']:
hosts = self.inventory.get_hosts(context.CLIARGS['host'])
if len(hosts) != 1:
raise AnsibleOptionsError("You must pass a single valid host to --host parameter")
myvars = self._get_host_variables(host=hosts[0])
# FIXME: should we template first?
results = self.dump(myvars)
else:
if context.CLIARGS['subset']:
# not doing single host, set limit in general if given
self.inventory.subset(context.CLIARGS['subset'])
if context.CLIARGS['graph']:
results = self.inventory_graph()
elif context.CLIARGS['list']:
top = self._get_group('all')
if context.CLIARGS['yaml']:
results = self.yaml_inventory(top)
elif context.CLIARGS['toml']:
results = self.toml_inventory(top)
else:
results = self.json_inventory(top)
results = self.dump(results)
if results:
outfile = context.CLIARGS['output_file']
if outfile is None:
# FIXME: pager?
display.display(results)
else:
try:
with open(to_bytes(outfile), 'wb') as f:
f.write(to_bytes(results))
except (OSError, IOError) as e:
raise AnsibleError('Unable to write to destination file (%s): %s' % (to_native(outfile), to_native(e)))
sys.exit(0)
sys.exit(1)
@staticmethod
def dump(stuff):
if context.CLIARGS['yaml']:
import yaml
from ansible.parsing.yaml.dumper import AnsibleDumper
# DTFIX-RELEASE: need shared infra to smuggle custom kwargs to dumpers, since yaml.dump cannot (as of PyYAML 6.0.1)
dumper = functools.partial(AnsibleDumper, dump_vault_tags=True)
results = to_text(yaml.dump(stuff, Dumper=dumper, default_flow_style=False, allow_unicode=True))
elif context.CLIARGS['toml']:
results = toml_dumps(stuff)
else:
results = json.dumps(stuff, cls=_inventory_legacy.Encoder, sort_keys=True, indent=4)
return results
def _get_group_variables(self, group):
# get info from inventory source
res = group.get_vars()
# Always load vars plugins
res = combine_vars(res, get_vars_from_inventory_sources(self.loader, self.inventory._sources, [group], 'all'))
if context.CLIARGS['basedir']:
res = combine_vars(res, get_vars_from_path(self.loader, context.CLIARGS['basedir'], [group], 'all'))
if group.priority != 1:
res['ansible_group_priority'] = group.priority
return self._remove_internal(res)
def _get_host_variables(self, host):
if context.CLIARGS['export']:
# only get vars defined directly host
hostvars = host.get_vars()
# Always load vars plugins
hostvars = combine_vars(hostvars, get_vars_from_inventory_sources(self.loader, self.inventory._sources, [host], 'all'))
if context.CLIARGS['basedir']:
hostvars = combine_vars(hostvars, get_vars_from_path(self.loader, context.CLIARGS['basedir'], [host], 'all'))
else:
# get all vars flattened by host, but skip magic hostvars
hostvars = self.vm.get_vars(host=host, include_hostvars=False, stage='all')
return self._remove_internal(hostvars)
def _get_group(self, gname):
group = self.inventory.groups.get(gname)
return group
@staticmethod
def _remove_internal(dump):
for internal in C.INTERNAL_STATIC_VARS:
if internal in dump:
del dump[internal]
return dump
@staticmethod
def _remove_empty_keys(dump):
# remove empty keys
for x in ('hosts', 'vars', 'children'):
if x in dump and not dump[x]:
del dump[x]
@staticmethod
def _show_vars(dump, depth):
result = []
for (name, val) in sorted(dump.items()):
result.append(InventoryCLI._graph_name('{%s = %s}' % (name, val), depth))
return result
@staticmethod
def _graph_name(name, depth=0):
if depth:
name = " |" * (depth) + "--%s" % name
return name
def _graph_group(self, group, depth=0):
result = [self._graph_name('@%s:' % group.name, depth)]
depth = depth + 1
for kid in group.child_groups:
result.extend(self._graph_group(kid, depth))
if group.name != 'all':
for host in group.hosts:
result.append(self._graph_name(host.name, depth))
if context.CLIARGS['show_vars']:
result.extend(self._show_vars(self._get_host_variables(host), depth + 1))
if context.CLIARGS['show_vars']:
result.extend(self._show_vars(self._get_group_variables(group), depth))
return result
def inventory_graph(self):
start_at = self._get_group(context.CLIARGS['pattern'])
if start_at:
return '\n'.join(self._graph_group(start_at))
else:
raise AnsibleOptionsError("Pattern must be valid group name when using --graph")
def json_inventory(self, top):
seen_groups = set()
def format_group(group, available_hosts):
results = {}
results[group.name] = {}
if group.name != 'all':
results[group.name]['hosts'] = [h.name for h in group.hosts if h.name in available_hosts]
results[group.name]['children'] = []
for subgroup in group.child_groups:
results[group.name]['children'].append(subgroup.name)
if subgroup.name not in seen_groups:
results.update(format_group(subgroup, available_hosts))
seen_groups.add(subgroup.name)
if context.CLIARGS['export']:
results[group.name]['vars'] = self._get_group_variables(group)
self._remove_empty_keys(results[group.name])
# remove empty groups
if not results[group.name]:
del results[group.name]
return results
hosts = self.inventory.get_hosts(top.name)
results = format_group(top, frozenset(h.name for h in hosts))
# populate meta
results['_meta'] = {
'hostvars': {},
'profile': _inventory_legacy.Encoder.profile_name,
}
for host in hosts:
hvars = self._get_host_variables(host)
if hvars:
results['_meta']['hostvars'][host.name] = hvars
return results
def yaml_inventory(self, top):
seen_hosts = set()
seen_groups = set()
def format_group(group, available_hosts):
results = {}
# initialize group + vars
results[group.name] = {}
# subgroups
results[group.name]['children'] = {}
for subgroup in group.child_groups:
if subgroup.name != 'all':
if subgroup.name in seen_groups:
results[group.name]['children'].update({subgroup.name: {}})
else:
results[group.name]['children'].update(format_group(subgroup, available_hosts))
seen_groups.add(subgroup.name)
# hosts for group
results[group.name]['hosts'] = {}
if group.name != 'all':
for h in group.hosts:
if h.name not in available_hosts:
continue # observe limit
myvars = {}
if h.name not in seen_hosts: # avoid defining host vars more than once
seen_hosts.add(h.name)
myvars = self._get_host_variables(host=h)
results[group.name]['hosts'][h.name] = myvars
if context.CLIARGS['export']:
gvars = self._get_group_variables(group)
if gvars:
results[group.name]['vars'] = gvars
self._remove_empty_keys(results[group.name])
# remove empty groups
if not results[group.name]:
del results[group.name]
return results
available_hosts = frozenset(h.name for h in self.inventory.get_hosts(top.name))
return format_group(top, available_hosts)
def toml_inventory(self, top):
seen_hosts = set()
seen_hosts = set()
has_ungrouped = bool(next(g.hosts for g in top.child_groups if g.name == 'ungrouped'))
def format_group(group, available_hosts):
results = {}
results[group.name] = {}
results[group.name]['children'] = []
for subgroup in group.child_groups:
if subgroup.name == 'ungrouped' and not has_ungrouped:
continue
if group.name != 'all':
results[group.name]['children'].append(subgroup.name)
results.update(format_group(subgroup, available_hosts))
if group.name != 'all':
for host in group.hosts:
if host.name not in available_hosts:
continue
if host.name not in seen_hosts:
seen_hosts.add(host.name)
host_vars = self._get_host_variables(host=host)
else:
host_vars = {}
try:
results[group.name]['hosts'][host.name] = host_vars
except KeyError:
results[group.name]['hosts'] = {host.name: host_vars}
if context.CLIARGS['export']:
results[group.name]['vars'] = self._get_group_variables(group)
self._remove_empty_keys(results[group.name])
# remove empty groups
if not results[group.name]:
del results[group.name]
return results
available_hosts = frozenset(h.name for h in self.inventory.get_hosts(top.name))
results = format_group(top, available_hosts)
return results
def toml_dumps(data: t.Any) -> str:
try:
from tomli_w import dumps as _tomli_w_dumps
except ImportError:
pass
else:
return _tomli_w_dumps(data)
raise AnsibleRuntimeError('The Python library "tomli-w" is required when using the TOML output format.')
def main(args=None):
InventoryCLI.cli_executor(args)
if __name__ == '__main__':
main()
ansible_core-2.19.0b4/lib/ansible/cli/playbook.py 0000755 0000000 0000000 00000024462 15010426755 020360 0 ustar 00root root #!/usr/bin/env python
# (c) 2012, Michael DeHaan
# Copyright: (c) 2018, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# PYTHON_ARGCOMPLETE_OK
from __future__ import annotations
# ansible.cli needs to be imported first, to ensure the source bin/* scripts run that code first
from ansible.cli import CLI
import os
import stat
from ansible import constants as C
from ansible import context
from ansible.cli.arguments import option_helpers as opt_help
from ansible.errors import AnsibleError
from ansible.executor.playbook_executor import PlaybookExecutor
from ansible.module_utils.common.text.converters import to_bytes
from ansible.playbook.block import Block
from ansible.plugins.loader import add_all_plugin_dirs
from ansible.utils.collection_loader import AnsibleCollectionConfig
from ansible.utils.collection_loader._collection_finder import _get_collection_name_from_path, _get_collection_playbook_path
from ansible.utils.display import Display
display = Display()
class PlaybookCLI(CLI):
""" the tool to run *Ansible playbooks*, which are a configuration and multinode deployment system.
See the project home page (https://docs.ansible.com) for more information. """
name = 'ansible-playbook'
USES_CONNECTION = True
def init_parser(self):
# create parser for CLI options
super(PlaybookCLI, self).init_parser(
usage="%prog [options] playbook.yml [playbook2 ...]",
desc="Runs Ansible playbooks, executing the defined tasks on the targeted hosts.")
opt_help.add_connect_options(self.parser)
opt_help.add_meta_options(self.parser)
opt_help.add_runas_options(self.parser)
opt_help.add_subset_options(self.parser)
opt_help.add_check_options(self.parser)
opt_help.add_inventory_options(self.parser)
opt_help.add_runtask_options(self.parser)
opt_help.add_vault_options(self.parser)
opt_help.add_fork_options(self.parser)
opt_help.add_module_options(self.parser)
# ansible playbook specific opts
self.parser.add_argument('--syntax-check', dest='syntax', action='store_true',
help="perform a syntax check on the playbook, but do not execute it")
self.parser.add_argument('--list-tasks', dest='listtasks', action='store_true',
help="list all tasks that would be executed")
self.parser.add_argument('--list-tags', dest='listtags', action='store_true',
help="list all available tags")
self.parser.add_argument('--step', dest='step', action='store_true',
help="one-step-at-a-time: confirm each task before running")
self.parser.add_argument('--start-at-task', dest='start_at_task',
help="start the playbook at the task matching this name")
self.parser.add_argument('args', help='Playbook(s)', metavar='playbook', nargs='+')
def post_process_args(self, options):
# for listing, we need to know if user had tag input
# capture here as parent function sets defaults for tags
havetags = bool(options.tags or options.skip_tags)
options = super(PlaybookCLI, self).post_process_args(options)
if options.listtags:
# default to all tags (including never), when listing tags
# unless user specified tags
if not havetags:
options.tags = ['never', 'all']
display.verbosity = options.verbosity
self.validate_conflicts(options, runas_opts=True, fork_opts=True)
return options
def run(self):
super(PlaybookCLI, self).run()
# Note: slightly wrong, this is written so that implicit localhost
# manages passwords
sshpass = None
becomepass = None
passwords = {}
# initial error check, to make sure all specified playbooks are accessible
# before we start running anything through the playbook executor
# also prep plugin paths
b_playbook_dirs = []
for playbook in context.CLIARGS['args']:
# resolve if it is collection playbook with FQCN notation, if not, leaves unchanged
resource = _get_collection_playbook_path(playbook)
if resource is not None:
playbook_collection = resource[2]
else:
# not an FQCN so must be a file
if not os.path.exists(playbook):
raise AnsibleError("the playbook: %s could not be found" % playbook)
if not (os.path.isfile(playbook) or stat.S_ISFIFO(os.stat(playbook).st_mode)):
raise AnsibleError("the playbook: %s does not appear to be a file" % playbook)
# check if playbook is from collection (path can be passed directly)
playbook_collection = _get_collection_name_from_path(playbook)
# don't add collection playbooks to adjacency search path
if not playbook_collection:
# setup dirs to enable loading plugins from all playbooks in case they add callbacks/inventory/etc
b_playbook_dir = os.path.dirname(os.path.abspath(to_bytes(playbook, errors='surrogate_or_strict')))
add_all_plugin_dirs(b_playbook_dir)
b_playbook_dirs.append(b_playbook_dir)
if b_playbook_dirs:
# allow collections adjacent to these playbooks
# we use list copy to avoid opening up 'adjacency' in the previous loop
AnsibleCollectionConfig.playbook_paths = b_playbook_dirs
# don't deal with privilege escalation or passwords when we don't need to
if not (context.CLIARGS['listhosts'] or context.CLIARGS['listtasks'] or
context.CLIARGS['listtags'] or context.CLIARGS['syntax']):
(sshpass, becomepass) = self.ask_passwords()
passwords = {'conn_pass': sshpass, 'become_pass': becomepass}
# create base objects
loader, inventory, variable_manager = self._play_prereqs()
# (which is not returned in list_hosts()) is taken into account for
# warning if inventory is empty. But it can't be taken into account for
# checking if limit doesn't match any hosts. Instead we don't worry about
# limit if only implicit localhost was in inventory to start with.
#
# Fix this when we rewrite inventory by making localhost a real host (and thus show up in list_hosts())
CLI.get_host_list(inventory, context.CLIARGS['subset'])
# create the playbook executor, which manages running the plays via a task queue manager
pbex = PlaybookExecutor(playbooks=context.CLIARGS['args'], inventory=inventory,
variable_manager=variable_manager, loader=loader,
passwords=passwords)
results = pbex.run()
if isinstance(results, list):
for p in results:
display.display('\nplaybook: %s' % p['playbook'])
for idx, play in enumerate(p['plays']):
if play._included_path is not None:
loader.set_basedir(play._included_path)
else:
pb_dir = os.path.realpath(os.path.dirname(p['playbook']))
loader.set_basedir(pb_dir)
# show host list if we were able to template into a list
try:
host_list = ','.join(play.hosts)
except TypeError:
host_list = ''
msg = "\n play #%d (%s): %s" % (idx + 1, host_list, play.name)
mytags = set(play.tags)
msg += '\tTAGS: [%s]' % (','.join(mytags))
if context.CLIARGS['listhosts']:
playhosts = set(inventory.get_hosts(play.hosts))
msg += "\n pattern: %s\n hosts (%d):" % (play.hosts, len(playhosts))
for host in playhosts:
msg += "\n %s" % host
display.display(msg)
all_tags = set()
if context.CLIARGS['listtags'] or context.CLIARGS['listtasks']:
taskmsg = ''
if context.CLIARGS['listtasks']:
taskmsg = ' tasks:\n'
def _process_block(b):
taskmsg = ''
for task in b.block:
if isinstance(task, Block):
taskmsg += _process_block(task)
else:
if task.action in C._ACTION_META and task.implicit:
continue
all_tags.update(task.tags)
if context.CLIARGS['listtasks']:
cur_tags = list(mytags.union(set(task.tags)))
cur_tags.sort()
if task.name:
taskmsg += " %s" % task.get_name()
else:
taskmsg += " %s" % task.action
taskmsg += "\tTAGS: [%s]\n" % ', '.join(cur_tags)
return taskmsg
all_vars = variable_manager.get_vars(play=play)
for block in play.compile():
block = block.filter_tagged_tasks(all_vars)
if not block.has_tasks():
continue
taskmsg += _process_block(block)
if context.CLIARGS['listtags']:
cur_tags = list(mytags.union(all_tags))
cur_tags.sort()
taskmsg += " TASK TAGS: [%s]\n" % ', '.join(cur_tags)
display.display(taskmsg)
return 0
else:
return results
def main(args=None):
PlaybookCLI.cli_executor(args)
if __name__ == '__main__':
main()
ansible_core-2.19.0b4/lib/ansible/cli/pull.py 0000755 0000000 0000000 00000043771 15010426755 017520 0 ustar 00root root #!/usr/bin/env python
# Copyright: (c) 2012, Michael DeHaan
# Copyright: (c) 2018, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# PYTHON_ARGCOMPLETE_OK
from __future__ import annotations
# ansible.cli needs to be imported first, to ensure the source bin/* scripts run that code first
from ansible.cli import CLI
import datetime
import os
import platform
import secrets
import shlex
import shutil
import socket
import sys
import time
from ansible import constants as C
from ansible import context
from ansible.cli.arguments import option_helpers as opt_help
from ansible.errors import AnsibleOptionsError
from ansible.module_utils.common.text.converters import to_native, to_text
from ansible.plugins.loader import module_loader
from ansible.utils.cmd_functions import run_cmd
from ansible.utils.display import Display
display = Display()
SAFE_OUTPUT_ENV = {
'ANSIBLE_CALLBACK_RESULT_FORMAT': 'json',
'ANSIBLE_LOAD_CALLBACK_PLUGINS': '0',
}
def safe_output_env(f):
def wrapper(*args, **kwargs):
orig = {}
for k, v in SAFE_OUTPUT_ENV.items():
orig[k] = os.environ.get(k, None)
os.environ[k] = v
result = f(*args, **kwargs)
for key in orig.keys():
if orig[key] is None:
del os.environ[key]
else:
os.environ[key] = orig[key]
return result
return wrapper
class PullCLI(CLI):
""" Used to pull a remote copy of ansible on each managed node,
each set to run via cron and update playbook source via a source repository.
This inverts the default *push* architecture of ansible into a *pull* architecture,
which has near-limitless scaling potential.
None of the CLI tools are designed to run concurrently with themselves,
you should use an external scheduler and/or locking to ensure there are no clashing operations.
The setup playbook can be tuned to change the cron frequency, logging locations, and parameters to ansible-pull.
This is useful both for extreme scale-out and periodic remediation.
Usage of the 'fetch' module to retrieve logs from ansible-pull runs would be an
excellent way to gather and analyze remote logs from ansible-pull.
"""
name = 'ansible-pull'
DEFAULT_REPO_TYPE = 'git'
DEFAULT_PLAYBOOK = 'local.yml'
REPO_CHOICES = ('git', 'subversion', 'hg', 'bzr')
PLAYBOOK_ERRORS = {
1: 'File does not exist',
2: 'File is not readable',
}
ARGUMENTS = {'playbook.yml': 'The name of one the YAML format files to run as an Ansible playbook. '
'This can be a relative path within the checkout. By default, Ansible will '
"look for a playbook based on the host's fully-qualified domain name, "
'on the host hostname and finally a playbook named *local.yml*.', }
SKIP_INVENTORY_DEFAULTS = True
@staticmethod
def _get_inv_cli():
inv_opts = ''
if context.CLIARGS.get('inventory', False):
for inv in context.CLIARGS['inventory']:
if isinstance(inv, list):
inv_opts += " -i '%s' " % ','.join(inv)
elif ',' in inv or os.path.exists(inv):
inv_opts += ' -i %s ' % inv
return inv_opts
def init_parser(self):
""" Specific args/option parser for pull """
# signature is different from parent as caller should not need to add usage/desc
super(PullCLI, self).init_parser(
usage='%prog -U [options] []',
desc="pulls playbooks from a VCS repo and executes them on target host")
# Do not add check_options as there's a conflict with --checkout/-C
opt_help.add_connect_options(self.parser)
opt_help.add_vault_options(self.parser)
opt_help.add_runtask_options(self.parser)
opt_help.add_subset_options(self.parser)
opt_help.add_inventory_options(self.parser)
opt_help.add_module_options(self.parser)
opt_help.add_runas_prompt_options(self.parser)
self.parser.add_argument('args', help='Playbook(s)', metavar='playbook.yml', nargs='*')
# options unique to pull
self.parser.add_argument('--purge', default=False, action='store_true', help='purge checkout after playbook run')
self.parser.add_argument('-o', '--only-if-changed', dest='ifchanged', default=False, action='store_true',
help='only run the playbook if the repository has been updated')
self.parser.add_argument('-s', '--sleep', dest='sleep', default=None,
help='sleep for random interval (between 0 and n number of seconds) before starting. '
'This is a useful way to disperse git requests')
self.parser.add_argument('-f', '--force', dest='force', default=False, action='store_true',
help='run the playbook even if the repository could not be updated')
self.parser.add_argument('-d', '--directory', dest='dest', default=None, type=opt_help.unfrack_path(),
help='path to the directory to which Ansible will checkout the repository.')
self.parser.add_argument('-U', '--url', dest='url', default=None, help='URL of the playbook repository')
self.parser.add_argument('--full', dest='fullclone', action='store_true', help='Do a full clone, instead of a shallow one.')
# TODO: resolve conflict with check mode, added manually below
self.parser.add_argument('-C', '--checkout', dest='checkout',
help='branch/tag/commit to checkout. Defaults to behavior of repository module.')
self.parser.add_argument('--accept-host-key', default=False, dest='accept_host_key', action='store_true',
help='adds the hostkey for the repo url if not already added')
# Overloaded with adhoc ... but really passthrough to adhoc
self.parser.add_argument('-m', '--module-name', dest='module_name', default=self.DEFAULT_REPO_TYPE,
help='Repository module name, which ansible will use to check out the repo. Choices are %s. Default is %s.'
% (self.REPO_CHOICES, self.DEFAULT_REPO_TYPE))
self.parser.add_argument('--verify-commit', dest='verify', default=False, action='store_true',
help='verify GPG signature of checked out commit, if it fails abort running the playbook. '
'This needs the corresponding VCS module to support such an operation')
self.parser.add_argument('--clean', dest='clean', default=False, action='store_true',
help='modified files in the working repository will be discarded')
self.parser.add_argument('--track-subs', dest='tracksubs', default=False, action='store_true',
help='submodules will track the latest changes. This is equivalent to specifying the --remote flag to git submodule update')
# add a subset of the check_opts flag group manually, as the full set's
# shortcodes conflict with above --checkout/-C, see to-do above
self.parser.add_argument("--check", default=False, dest='check', action='store_true',
help="don't make any changes; instead, try to predict some of the changes that may occur")
self.parser.add_argument("--diff", default=C.DIFF_ALWAYS, dest='diff', action='store_true',
help="when changing (small) files and templates, show the differences in those files; works great with --check")
def post_process_args(self, options):
options = super(PullCLI, self).post_process_args(options)
if not options.dest:
hostname = socket.getfqdn()
# use a hostname dependent directory, in case of $HOME on nfs
options.dest = os.path.join(C.ANSIBLE_HOME, 'pull', hostname)
if os.path.exists(options.dest) and not os.path.isdir(options.dest):
raise AnsibleOptionsError("%s is not a valid or accessible directory." % options.dest)
if options.sleep:
try:
secs = secrets.randbelow(int(options.sleep))
options.sleep = secs
except ValueError:
raise AnsibleOptionsError("%s is not a number." % options.sleep)
if not options.url:
raise AnsibleOptionsError("URL for repository not specified, use -h for help")
if options.module_name not in self.REPO_CHOICES:
raise AnsibleOptionsError("Unsupported repo module %s, choices are %s" % (options.module_name, ','.join(self.REPO_CHOICES)))
display.verbosity = options.verbosity
self.validate_conflicts(options)
return options
def run(self):
""" use Runner lib to do SSH things """
super(PullCLI, self).run()
# log command line
now = datetime.datetime.now()
display.display(now.strftime("Starting Ansible Pull at %F %T"))
display.display(' '.join(sys.argv))
# Build Checkout command
# Now construct the ansible command
node = platform.node()
host = socket.getfqdn()
hostnames = ','.join(set([host, node, host.split('.')[0], node.split('.')[0]]))
if hostnames:
limit_opts = 'localhost,%s,127.0.0.1' % hostnames
else:
limit_opts = 'localhost,127.0.0.1'
base_opts = '-c local '
if context.CLIARGS['verbosity'] > 0:
base_opts += ' -%s' % ''.join(["v" for dummy in range(0, context.CLIARGS['verbosity'])])
# Attempt to use the inventory passed in as an argument
# It might not yet have been downloaded so use localhost as default
inv_opts = self._get_inv_cli()
if not inv_opts:
inv_opts = " -i localhost, "
# avoid interpreter discovery since we already know which interpreter to use on localhost
inv_opts += '-e %s ' % shlex.quote('ansible_python_interpreter=%s' % sys.executable)
# SCM specific options
if context.CLIARGS['module_name'] == 'git':
repo_opts = "name=%s dest=%s" % (context.CLIARGS['url'], context.CLIARGS['dest'])
if context.CLIARGS['checkout']:
repo_opts += ' version=%s' % context.CLIARGS['checkout']
if context.CLIARGS['accept_host_key']:
repo_opts += ' accept_hostkey=yes'
if context.CLIARGS['private_key_file']:
repo_opts += ' key_file=%s' % context.CLIARGS['private_key_file']
if context.CLIARGS['verify']:
repo_opts += ' verify_commit=yes'
if context.CLIARGS['tracksubs']:
repo_opts += ' track_submodules=yes'
if not context.CLIARGS['fullclone']:
repo_opts += ' depth=1'
elif context.CLIARGS['module_name'] == 'subversion':
repo_opts = "repo=%s dest=%s" % (context.CLIARGS['url'], context.CLIARGS['dest'])
if context.CLIARGS['checkout']:
repo_opts += ' revision=%s' % context.CLIARGS['checkout']
if not context.CLIARGS['fullclone']:
repo_opts += ' export=yes'
elif context.CLIARGS['module_name'] == 'hg':
repo_opts = "repo=%s dest=%s" % (context.CLIARGS['url'], context.CLIARGS['dest'])
if context.CLIARGS['checkout']:
repo_opts += ' revision=%s' % context.CLIARGS['checkout']
elif context.CLIARGS['module_name'] == 'bzr':
repo_opts = "name=%s dest=%s" % (context.CLIARGS['url'], context.CLIARGS['dest'])
if context.CLIARGS['checkout']:
repo_opts += ' version=%s' % context.CLIARGS['checkout']
else:
raise AnsibleOptionsError('Unsupported (%s) SCM module for pull, choices are: %s'
% (context.CLIARGS['module_name'],
','.join(self.REPO_CHOICES)))
# options common to all supported SCMS
if context.CLIARGS['clean']:
repo_opts += ' force=yes'
path = module_loader.find_plugin(context.CLIARGS['module_name'])
if path is None:
raise AnsibleOptionsError(("module '%s' not found.\n" % context.CLIARGS['module_name']))
bin_path = os.path.dirname(os.path.abspath(sys.argv[0]))
# hardcode local and inventory/host as this is just meant to fetch the repo
cmd = '%s/ansible %s %s -m %s -a "%s" all -l "%s"' % (bin_path, inv_opts, base_opts,
context.CLIARGS['module_name'],
repo_opts, limit_opts)
for ev in context.CLIARGS['extra_vars']:
cmd += ' -e %s' % shlex.quote(ev)
# Nap?
if context.CLIARGS['sleep']:
display.display("Sleeping for %d seconds..." % context.CLIARGS['sleep'])
time.sleep(context.CLIARGS['sleep'])
# RUN the Checkout command
display.debug("running ansible with VCS module to checkout repo")
display.vvvv('EXEC: %s' % cmd)
rc, b_out, b_err = safe_output_env(run_cmd)(cmd, live=True)
if rc != 0:
if context.CLIARGS['force']:
display.warning("Unable to update repository. Continuing with (forced) run of playbook.")
else:
return rc
elif context.CLIARGS['ifchanged']:
# detect json/yaml/header, any count as 'changed'
for detect in (b'"changed": true', b"changed: True", b"| CHANGED =>"):
if detect in b_out:
break
else:
# no change, we bail
display.display(f"Repository has not changed, quitting: {b_out!r}")
return 0
playbook = self.select_playbook(context.CLIARGS['dest'])
if playbook is None:
raise AnsibleOptionsError("Could not find a playbook to run.")
# Build playbook command
cmd = '%s/ansible-playbook %s %s' % (bin_path, base_opts, playbook)
if context.CLIARGS['vault_password_files']:
for vault_password_file in context.CLIARGS['vault_password_files']:
cmd += " --vault-password-file=%s" % vault_password_file
if context.CLIARGS['vault_ids']:
for vault_id in context.CLIARGS['vault_ids']:
cmd += " --vault-id=%s" % vault_id
if context.CLIARGS['become_password_file']:
cmd += " --become-password-file=%s" % context.CLIARGS['become_password_file']
if context.CLIARGS['connection_password_file']:
cmd += " --connection-password-file=%s" % context.CLIARGS['connection_password_file']
for ev in context.CLIARGS['extra_vars']:
cmd += ' -e %s' % shlex.quote(ev)
if context.CLIARGS['become_ask_pass']:
cmd += ' --ask-become-pass'
if context.CLIARGS['skip_tags']:
cmd += ' --skip-tags "%s"' % to_native(u','.join(context.CLIARGS['skip_tags']))
if context.CLIARGS['tags']:
cmd += ' -t "%s"' % to_native(u','.join(context.CLIARGS['tags']))
if context.CLIARGS['subset']:
cmd += ' -l "%s"' % context.CLIARGS['subset']
else:
cmd += ' -l "%s"' % limit_opts
if context.CLIARGS['check']:
cmd += ' -C'
if context.CLIARGS['diff']:
cmd += ' -D'
if context.CLIARGS['flush_cache']:
cmd += ' --flush-cache'
os.chdir(context.CLIARGS['dest'])
# redo inventory options as new files might exist now
inv_opts = self._get_inv_cli()
if inv_opts:
cmd += inv_opts
# RUN THE PLAYBOOK COMMAND
display.debug("running ansible-playbook to do actual work")
display.debug('EXEC: %s' % cmd)
rc, b_out, b_err = run_cmd(cmd, live=True)
if context.CLIARGS['purge']:
os.chdir('/')
try:
display.debug("removing: %s" % context.CLIARGS['dest'])
shutil.rmtree(context.CLIARGS['dest'])
except Exception as e:
display.error(u"Failed to remove %s: %s" % (context.CLIARGS['dest'], to_text(e)))
return rc
@staticmethod
def try_playbook(path):
if not os.path.exists(path):
return 1
if not os.access(path, os.R_OK):
return 2
return 0
@staticmethod
def select_playbook(path):
playbook = None
errors = []
if context.CLIARGS['args'] and context.CLIARGS['args'][0] is not None:
playbooks = []
for book in context.CLIARGS['args']:
book_path = os.path.join(path, book)
rc = PullCLI.try_playbook(book_path)
if rc != 0:
errors.append("%s: %s" % (book_path, PullCLI.PLAYBOOK_ERRORS[rc]))
continue
playbooks.append(book_path)
if 0 < len(errors):
display.warning("\n".join(errors))
elif len(playbooks) == len(context.CLIARGS['args']):
playbook = " ".join(playbooks)
return playbook
else:
fqdn = socket.getfqdn()
hostpb = os.path.join(path, fqdn + '.yml')
shorthostpb = os.path.join(path, fqdn.split('.')[0] + '.yml')
localpb = os.path.join(path, PullCLI.DEFAULT_PLAYBOOK)
for pb in [hostpb, shorthostpb, localpb]:
rc = PullCLI.try_playbook(pb)
if rc == 0:
playbook = pb
break
else:
errors.append("%s: %s" % (pb, PullCLI.PLAYBOOK_ERRORS[rc]))
if playbook is None:
display.warning("\n".join(errors))
return playbook
def main(args=None):
PullCLI.cli_executor(args)
if __name__ == '__main__':
main()
ansible_core-2.19.0b4/lib/ansible/cli/scripts/ 0000755 0000000 0000000 00000000000 15010426755 017642 5 ustar 00root root ansible_core-2.19.0b4/lib/ansible/cli/scripts/__init__.py 0000644 0000000 0000000 00000000000 15010426755 021741 0 ustar 00root root ansible_core-2.19.0b4/lib/ansible/cli/scripts/ansible_connection_cli_stub.py 0000644 0000000 0000000 00000031502 15010426755 025735 0 ustar 00root root # Copyright: (c) 2017, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import annotations
import fcntl
import io
import os
import pickle
import signal
import socket
import sys
import time
import traceback
import errno
import json
from contextlib import contextmanager
from ansible import constants as C
from ansible.cli.arguments import option_helpers as opt_help
from ansible.module_utils.common.text.converters import to_bytes, to_text
from ansible.module_utils.connection import Connection, ConnectionError, send_data, recv_data
from ansible.module_utils.service import fork_process
from ansible.module_utils._internal._json._profiles import _tagless
from ansible.playbook.play_context import PlayContext
from ansible.plugins.loader import connection_loader, init_plugin_loader
from ansible.utils.path import unfrackpath, makedirs_safe
from ansible.utils.display import Display
from ansible.utils.jsonrpc import JsonRpcServer
display = Display()
def read_stream(byte_stream):
size = int(byte_stream.readline().strip())
data = byte_stream.read(size)
if len(data) < size:
raise Exception("EOF found before data was complete")
return data
@contextmanager
def file_lock(lock_path):
"""
Uses contextmanager to create and release a file lock based on the
given path. This allows us to create locks using `with file_lock()`
to prevent deadlocks related to failure to unlock properly.
"""
lock_fd = os.open(lock_path, os.O_RDWR | os.O_CREAT, 0o600)
fcntl.lockf(lock_fd, fcntl.LOCK_EX)
yield
fcntl.lockf(lock_fd, fcntl.LOCK_UN)
os.close(lock_fd)
class ConnectionProcess(object):
"""
The connection process wraps around a Connection object that manages
the connection to a remote device that persists over the playbook
"""
def __init__(self, fd, play_context, socket_path, original_path, task_uuid=None, ansible_playbook_pid=None):
self.play_context = play_context
self.socket_path = socket_path
self.original_path = original_path
self._task_uuid = task_uuid
self.fd = fd
self.exception = None
self.srv = JsonRpcServer()
self.sock = None
self.connection = None
self._ansible_playbook_pid = ansible_playbook_pid
def start(self, options):
messages = list()
result = {}
try:
messages.append(('vvvv', 'control socket path is %s' % self.socket_path))
# If this is a relative path (~ gets expanded later) then plug the
# key's path on to the directory we originally came from, so we can
# find it now that our cwd is /
if self.play_context.private_key_file and self.play_context.private_key_file[0] not in '~/':
self.play_context.private_key_file = os.path.join(self.original_path, self.play_context.private_key_file)
self.connection = connection_loader.get(self.play_context.connection, self.play_context, '/dev/null',
task_uuid=self._task_uuid, ansible_playbook_pid=self._ansible_playbook_pid)
try:
self.connection.set_options(direct=options)
except ConnectionError as exc:
messages.append(('debug', to_text(exc)))
raise ConnectionError('Unable to decode JSON from response set_options. See the debug log for more information.')
self.connection._socket_path = self.socket_path
self.srv.register(self.connection)
messages.extend([('vvvv', msg) for msg in sys.stdout.getvalue().splitlines()])
self.sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
self.sock.bind(self.socket_path)
self.sock.listen(1)
messages.append(('vvvv', 'local domain socket listeners started successfully'))
except Exception as exc:
messages.extend(self.connection.pop_messages())
result['error'] = to_text(exc)
result['exception'] = traceback.format_exc()
finally:
result['messages'] = messages
self.fd.write(json.dumps(result, cls=_tagless.Encoder))
self.fd.close()
def run(self):
try:
log_messages = self.connection.get_option('persistent_log_messages')
while not self.connection._conn_closed:
signal.signal(signal.SIGALRM, self.connect_timeout)
signal.signal(signal.SIGTERM, self.handler)
signal.alarm(self.connection.get_option('persistent_connect_timeout'))
self.exception = None
(s, addr) = self.sock.accept()
signal.alarm(0)
signal.signal(signal.SIGALRM, self.command_timeout)
while True:
data = recv_data(s)
if not data:
break
if log_messages:
display.display("jsonrpc request: %s" % data, log_only=True)
request = json.loads(to_text(data, errors='surrogate_or_strict'))
if request.get('method') == "exec_command" and not self.connection.connected:
self.connection._connect()
signal.alarm(self.connection.get_option('persistent_command_timeout'))
resp = self.srv.handle_request(data)
signal.alarm(0)
if log_messages:
display.display("jsonrpc response: %s" % resp, log_only=True)
send_data(s, to_bytes(resp))
s.close()
except Exception as e:
# socket.accept() will raise EINTR if the socket.close() is called
if hasattr(e, 'errno'):
if e.errno != errno.EINTR:
self.exception = traceback.format_exc()
else:
self.exception = traceback.format_exc()
finally:
# allow time for any exception msg send over socket to receive at other end before shutting down
time.sleep(0.1)
# when done, close the connection properly and cleanup the socket file so it can be recreated
self.shutdown()
def connect_timeout(self, signum, frame):
msg = 'persistent connection idle timeout triggered, timeout value is %s secs.\nSee the timeout setting options in the Network Debug and ' \
'Troubleshooting Guide.' % self.connection.get_option('persistent_connect_timeout')
display.display(msg, log_only=True)
raise Exception(msg)
def command_timeout(self, signum, frame):
msg = 'command timeout triggered, timeout value is %s secs.\nSee the timeout setting options in the Network Debug and Troubleshooting Guide.'\
% self.connection.get_option('persistent_command_timeout')
display.display(msg, log_only=True)
raise Exception(msg)
def handler(self, signum, frame):
msg = 'signal handler called with signal %s.' % signum
display.display(msg, log_only=True)
raise Exception(msg)
def shutdown(self):
""" Shuts down the local domain socket
"""
lock_path = unfrackpath("%s/.ansible_pc_lock_%s" % os.path.split(self.socket_path))
if os.path.exists(self.socket_path):
try:
if self.sock:
self.sock.close()
if self.connection:
self.connection.close()
if self.connection.get_option("persistent_log_messages"):
for _level, message in self.connection.pop_messages():
display.display(message, log_only=True)
except Exception:
pass
finally:
if os.path.exists(self.socket_path):
os.remove(self.socket_path)
setattr(self.connection, '_socket_path', None)
setattr(self.connection, '_connected', False)
if os.path.exists(lock_path):
os.remove(lock_path)
display.display('shutdown complete', log_only=True)
def main(args=None):
""" Called to initiate the connect to the remote device
"""
parser = opt_help.create_base_parser(prog=None)
opt_help.add_verbosity_options(parser)
parser.add_argument('playbook_pid')
parser.add_argument('task_uuid')
args = parser.parse_args(args[1:] if args is not None else args)
init_plugin_loader()
# initialize verbosity
display.verbosity = args.verbosity
rc = 0
result = {}
messages = list()
socket_path = None
# Need stdin as a byte stream
stdin = sys.stdin.buffer
# Note: update the below log capture code after Display.display() is refactored.
saved_stdout = sys.stdout
sys.stdout = io.StringIO()
try:
# read the play context data via stdin, which means depickling it
opts_data = read_stream(stdin)
init_data = read_stream(stdin)
pc_data = pickle.loads(init_data, encoding='bytes')
options = pickle.loads(opts_data, encoding='bytes')
play_context = PlayContext()
play_context.deserialize(pc_data)
except Exception as e:
rc = 1
result.update({
'error': to_text(e),
'exception': traceback.format_exc()
})
if rc == 0:
ssh = connection_loader.get('ssh', class_only=True)
ansible_playbook_pid = args.playbook_pid
task_uuid = args.task_uuid
cp = ssh._create_control_path(play_context.remote_addr, play_context.port, play_context.remote_user, play_context.connection, ansible_playbook_pid)
# create the persistent connection dir if need be and create the paths
# which we will be using later
tmp_path = unfrackpath(C.PERSISTENT_CONTROL_PATH_DIR)
makedirs_safe(tmp_path)
socket_path = unfrackpath(cp % dict(directory=tmp_path))
lock_path = unfrackpath("%s/.ansible_pc_lock_%s" % os.path.split(socket_path))
with file_lock(lock_path):
if not os.path.exists(socket_path):
messages.append(('vvvv', 'local domain socket does not exist, starting it'))
original_path = os.getcwd()
r, w = os.pipe()
pid = fork_process()
if pid == 0:
try:
os.close(r)
wfd = os.fdopen(w, 'w')
process = ConnectionProcess(wfd, play_context, socket_path, original_path, task_uuid, ansible_playbook_pid)
process.start(options)
except Exception:
messages.append(('error', traceback.format_exc()))
rc = 1
if rc == 0:
process.run()
else:
process.shutdown()
sys.exit(rc)
else:
os.close(w)
rfd = os.fdopen(r, 'r')
data = json.loads(rfd.read(), cls=_tagless.Decoder)
messages.extend(data.pop('messages'))
result.update(data)
else:
messages.append(('vvvv', 'found existing local domain socket, using it!'))
conn = Connection(socket_path)
try:
conn.set_options(direct=options)
except ConnectionError as exc:
messages.append(('debug', to_text(exc)))
raise ConnectionError('Unable to decode JSON from response set_options. See the debug log for more information.')
pc_data = to_text(init_data)
try:
conn.update_play_context(pc_data)
conn.set_check_prompt(task_uuid)
except Exception as exc:
# Only network_cli has update_play context and set_check_prompt, so missing this is
# not fatal e.g. netconf
if isinstance(exc, ConnectionError) and getattr(exc, 'code', None) == -32601:
pass
else:
result.update({
'error': to_text(exc),
'exception': traceback.format_exc()
})
if os.path.exists(socket_path):
messages.extend(Connection(socket_path).pop_messages())
messages.append(('vvvv', sys.stdout.getvalue()))
result.update({
'messages': messages,
'socket_path': socket_path
})
sys.stdout = saved_stdout
if 'exception' in result:
rc = 1
sys.stderr.write(json.dumps(result, cls=_tagless.Encoder))
else:
rc = 0
sys.stdout.write(json.dumps(result, cls=_tagless.Encoder))
sys.exit(rc)
if __name__ == '__main__':
main()
ansible_core-2.19.0b4/lib/ansible/cli/vault.py 0000755 0000000 0000000 00000055233 15010426755 017673 0 ustar 00root root #!/usr/bin/env python
# (c) 2014, James Tanner
# Copyright: (c) 2018, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# PYTHON_ARGCOMPLETE_OK
from __future__ import annotations
# ansible.cli needs to be imported first, to ensure the source bin/* scripts run that code first
from ansible.cli import CLI
import os
import sys
from ansible import constants as C
from ansible import context
from ansible.cli.arguments import option_helpers as opt_help
from ansible.errors import AnsibleOptionsError
from ansible.module_utils.common.text.converters import to_text, to_bytes
from ansible.parsing.dataloader import DataLoader
from ansible.parsing.vault import VaultEditor, VaultLib, match_encrypt_secret
from ansible.utils.display import Display
display = Display()
class VaultCLI(CLI):
""" can encrypt any structured data file used by Ansible.
This can include *group_vars/* or *host_vars/* inventory variables,
variables loaded by *include_vars* or *vars_files*, or variable files
passed on the ansible-playbook command line with *-e @file.yml* or *-e @file.json*.
Role variables and defaults are also included!
Because Ansible tasks, handlers, and other objects are data, these can also be encrypted with vault.
If you'd like to not expose what variables you are using, you can keep an individual task file entirely encrypted.
"""
name = 'ansible-vault'
FROM_STDIN = "stdin"
FROM_ARGS = "the command line args"
FROM_PROMPT = "the interactive prompt"
def __init__(self, args):
self.b_vault_pass = None
self.b_new_vault_pass = None
self.encrypt_string_read_stdin = False
self.encrypt_secret = None
self.encrypt_vault_id = None
self.new_encrypt_secret = None
self.new_encrypt_vault_id = None
super(VaultCLI, self).__init__(args)
def init_parser(self):
super(VaultCLI, self).init_parser(
desc="encryption/decryption utility for Ansible data files",
epilog="\nSee '%s --help' for more information on a specific command.\n\n" % os.path.basename(sys.argv[0])
)
common = opt_help.ArgumentParser(add_help=False)
opt_help.add_vault_options(common)
opt_help.add_verbosity_options(common)
subparsers = self.parser.add_subparsers(dest='action')
subparsers.required = True
output = opt_help.ArgumentParser(add_help=False)
output.add_argument('--output', default=None, dest='output_file',
help='output file name for encrypt or decrypt; use - for stdout',
type=opt_help.unfrack_path())
# For encrypting actions, we can also specify which of multiple vault ids should be used for encrypting
vault_id = opt_help.ArgumentParser(add_help=False)
vault_id.add_argument('--encrypt-vault-id', default=[], dest='encrypt_vault_id',
action='store', type=str,
help='the vault id used to encrypt (required if more than one vault-id is provided)')
create_parser = subparsers.add_parser('create', help='Create new vault encrypted file', parents=[vault_id, common])
create_parser.set_defaults(func=self.execute_create)
create_parser.add_argument('args', help='Filename', metavar='file_name', nargs='*')
create_parser.add_argument('--skip-tty-check', default=False, help='allows editor to be opened when no tty attached',
dest='skip_tty_check', action='store_true')
decrypt_parser = subparsers.add_parser('decrypt', help='Decrypt vault encrypted file or string', parents=[output, common])
decrypt_parser.set_defaults(func=self.execute_decrypt)
decrypt_parser.add_argument('args', help='Filename', metavar='file_name', nargs='*')
edit_parser = subparsers.add_parser('edit', help='Edit vault encrypted file', parents=[vault_id, common])
edit_parser.set_defaults(func=self.execute_edit)
edit_parser.add_argument('args', help='Filename', metavar='file_name', nargs='*')
view_parser = subparsers.add_parser('view', help='View vault encrypted file', parents=[common])
view_parser.set_defaults(func=self.execute_view)
view_parser.add_argument('args', help='Filename', metavar='file_name', nargs='*')
encrypt_parser = subparsers.add_parser('encrypt', help='Encrypt YAML file', parents=[common, output, vault_id])
encrypt_parser.set_defaults(func=self.execute_encrypt)
encrypt_parser.add_argument('args', help='Filename', metavar='file_name', nargs='*')
enc_str_parser = subparsers.add_parser('encrypt_string', help='Encrypt a string', parents=[common, output, vault_id])
enc_str_parser.set_defaults(func=self.execute_encrypt_string)
enc_str_parser.add_argument('args', help='String to encrypt', metavar='string_to_encrypt', nargs='*')
enc_str_parser.add_argument('-p', '--prompt', dest='encrypt_string_prompt',
action='store_true',
help="Prompt for the string to encrypt")
enc_str_parser.add_argument('--show-input', dest='show_string_input', default=False, action='store_true',
help='Do not hide input when prompted for the string to encrypt')
enc_str_parser.add_argument('-n', '--name', dest='encrypt_string_names',
action='append',
help="Specify the variable name")
enc_str_parser.add_argument('--stdin-name', dest='encrypt_string_stdin_name',
default=None,
help="Specify the variable name for stdin")
rekey_parser = subparsers.add_parser('rekey', help='Re-key a vault encrypted file', parents=[common, vault_id])
rekey_parser.set_defaults(func=self.execute_rekey)
rekey_new_group = rekey_parser.add_mutually_exclusive_group()
rekey_new_group.add_argument('--new-vault-password-file', default=None, dest='new_vault_password_file',
help="new vault password file for rekey", type=opt_help.unfrack_path())
rekey_new_group.add_argument('--new-vault-id', default=None, dest='new_vault_id', type=str,
help='the new vault identity to use for rekey')
rekey_parser.add_argument('args', help='Filename', metavar='file_name', nargs='*')
def post_process_args(self, options):
options = super(VaultCLI, self).post_process_args(options)
display.verbosity = options.verbosity
if options.vault_ids:
for vault_id in options.vault_ids:
if u';' in vault_id:
raise AnsibleOptionsError("'%s' is not a valid vault id. The character ';' is not allowed in vault ids" % vault_id)
if getattr(options, 'output_file', None) and len(options.args) > 1:
raise AnsibleOptionsError("At most one input file may be used with the --output option")
if options.action == 'encrypt_string':
if '-' in options.args or options.encrypt_string_stdin_name or (not options.args and not options.encrypt_string_prompt):
# prompting from stdin and reading from stdin are mutually exclusive, if stdin is still provided, it is ignored
self.encrypt_string_read_stdin = True
if options.encrypt_string_prompt and self.encrypt_string_read_stdin:
# should only trigger if prompt + either - or encrypt string stdin name were provided
raise AnsibleOptionsError('The --prompt option is not supported if also reading input from stdin')
return options
def run(self):
super(VaultCLI, self).run()
loader = DataLoader()
# set default restrictive umask
old_umask = os.umask(0o077)
vault_ids = list(context.CLIARGS['vault_ids'])
# there are 3 types of actions, those that just 'read' (decrypt, view) and only
# need to ask for a password once, and those that 'write' (create, encrypt) that
# ask for a new password and confirm it, and 'read/write (rekey) that asks for the
# old password, then asks for a new one and confirms it.
default_vault_ids = C.DEFAULT_VAULT_IDENTITY_LIST
vault_ids = default_vault_ids + vault_ids
action = context.CLIARGS['action']
# TODO: instead of prompting for these before, we could let VaultEditor
# call a callback when it needs it.
if action in ['decrypt', 'view', 'rekey', 'edit']:
vault_secrets = self.setup_vault_secrets(loader, vault_ids=vault_ids,
vault_password_files=list(context.CLIARGS['vault_password_files']),
ask_vault_pass=context.CLIARGS['ask_vault_pass'])
if not vault_secrets:
raise AnsibleOptionsError("A vault password is required to use Ansible's Vault")
if action in ['encrypt', 'encrypt_string', 'create']:
encrypt_vault_id = None
# no --encrypt-vault-id context.CLIARGS['encrypt_vault_id'] for 'edit'
if action not in ['edit']:
encrypt_vault_id = context.CLIARGS['encrypt_vault_id'] or C.DEFAULT_VAULT_ENCRYPT_IDENTITY
vault_secrets = None
vault_secrets = \
self.setup_vault_secrets(loader,
vault_ids=vault_ids,
vault_password_files=list(context.CLIARGS['vault_password_files']),
ask_vault_pass=context.CLIARGS['ask_vault_pass'],
create_new_password=True)
if len(vault_secrets) > 1 and not encrypt_vault_id:
raise AnsibleOptionsError("The vault-ids %s are available to encrypt. Specify the vault-id to encrypt with --encrypt-vault-id" %
','.join([x[0] for x in vault_secrets]))
if not vault_secrets:
raise AnsibleOptionsError("A vault password is required to use Ansible's Vault")
encrypt_secret = match_encrypt_secret(vault_secrets,
encrypt_vault_id=encrypt_vault_id)
# only one secret for encrypt for now, use the first vault_id and use its first secret
# TODO: exception if more than one?
self.encrypt_vault_id = encrypt_secret[0]
self.encrypt_secret = encrypt_secret[1]
if action in ['rekey']:
encrypt_vault_id = context.CLIARGS['encrypt_vault_id'] or C.DEFAULT_VAULT_ENCRYPT_IDENTITY
# print('encrypt_vault_id: %s' % encrypt_vault_id)
# print('default_encrypt_vault_id: %s' % default_encrypt_vault_id)
# new_vault_ids should only ever be one item, from
# load the default vault ids if we are using encrypt-vault-id
new_vault_ids = []
if encrypt_vault_id:
new_vault_ids = default_vault_ids
if context.CLIARGS['new_vault_id']:
new_vault_ids.append(context.CLIARGS['new_vault_id'])
new_vault_password_files = []
if context.CLIARGS['new_vault_password_file']:
new_vault_password_files.append(context.CLIARGS['new_vault_password_file'])
new_vault_secrets = \
self.setup_vault_secrets(loader,
vault_ids=new_vault_ids,
vault_password_files=new_vault_password_files,
ask_vault_pass=context.CLIARGS['ask_vault_pass'],
initialize_context=False,
create_new_password=True)
if not new_vault_secrets:
raise AnsibleOptionsError("A new vault password is required to use Ansible's Vault rekey")
# There is only one new_vault_id currently and one new_vault_secret, or we
# use the id specified in --encrypt-vault-id
new_encrypt_secret = match_encrypt_secret(new_vault_secrets,
encrypt_vault_id=encrypt_vault_id)
self.new_encrypt_vault_id = new_encrypt_secret[0]
self.new_encrypt_secret = new_encrypt_secret[1]
loader.set_vault_secrets(vault_secrets)
# FIXME: do we need to create VaultEditor here? its not reused
vault = VaultLib(vault_secrets)
self.editor = VaultEditor(vault)
context.CLIARGS['func']()
# and restore umask
os.umask(old_umask)
def execute_encrypt(self):
""" encrypt the supplied file using the provided vault secret """
if not context.CLIARGS['args'] and sys.stdin.isatty():
display.display("Reading plaintext input from stdin", stderr=True)
for f in context.CLIARGS['args'] or ['-']:
# FIXME: use the correct vau
self.editor.encrypt_file(f, self.encrypt_secret,
vault_id=self.encrypt_vault_id,
output_file=context.CLIARGS['output_file'])
if sys.stdout.isatty():
display.display("Encryption successful", stderr=True)
@staticmethod
def format_ciphertext_yaml(b_ciphertext, indent=None, name=None):
indent = indent or 10
block_format_var_name = ""
if name:
block_format_var_name = "%s: " % name
block_format_header = "%s!vault |" % block_format_var_name
lines = []
vault_ciphertext = to_text(b_ciphertext)
lines.append(block_format_header)
for line in vault_ciphertext.splitlines():
lines.append('%s%s' % (' ' * indent, line))
yaml_ciphertext = '\n'.join(lines)
return yaml_ciphertext
def execute_encrypt_string(self):
""" encrypt the supplied string using the provided vault secret """
b_plaintext = None
# Holds tuples (the_text, the_source_of_the_string, the variable name if its provided).
b_plaintext_list = []
# remove the non-option '-' arg (used to indicate 'read from stdin') from the candidate args so
# we don't add it to the plaintext list
args = [x for x in context.CLIARGS['args'] if x != '-']
# We can prompt and read input, or read from stdin, but not both.
if context.CLIARGS['encrypt_string_prompt']:
msg = "String to encrypt: "
name = None
name_prompt_response = display.prompt('Variable name (enter for no name): ')
# TODO: enforce var naming rules?
if name_prompt_response != "":
name = name_prompt_response
# TODO: could prompt for which vault_id to use for each plaintext string
# currently, it will just be the default
hide_input = not context.CLIARGS['show_string_input']
if hide_input:
msg = "String to encrypt (hidden): "
else:
msg = "String to encrypt:"
prompt_response = display.prompt(msg, private=hide_input)
if prompt_response == '':
raise AnsibleOptionsError('The plaintext provided from the prompt was empty, not encrypting')
b_plaintext = to_bytes(prompt_response)
b_plaintext_list.append((b_plaintext, self.FROM_PROMPT, name))
# read from stdin
if self.encrypt_string_read_stdin:
if sys.stdout.isatty():
display.display("Reading plaintext input from stdin. (ctrl-d to end input, twice if your content does not already have a newline)", stderr=True)
stdin_text = sys.stdin.read()
if stdin_text == '':
raise AnsibleOptionsError('stdin was empty, not encrypting')
if sys.stdout.isatty() and not stdin_text.endswith("\n"):
display.display("\n")
b_plaintext = to_bytes(stdin_text)
# defaults to None
name = context.CLIARGS['encrypt_string_stdin_name']
b_plaintext_list.append((b_plaintext, self.FROM_STDIN, name))
# use any leftover args as strings to encrypt
# Try to match args up to --name options
if context.CLIARGS.get('encrypt_string_names', False):
name_and_text_list = list(zip(context.CLIARGS['encrypt_string_names'], args))
# Some but not enough --name's to name each var
if len(args) > len(name_and_text_list):
# Trying to avoid ever showing the plaintext in the output, so this warning is vague to avoid that.
display.display('The number of --name options do not match the number of args.',
stderr=True)
display.display('The last named variable will be "%s". The rest will not have'
' names.' % context.CLIARGS['encrypt_string_names'][-1],
stderr=True)
# Add the rest of the args without specifying a name
for extra_arg in args[len(name_and_text_list):]:
name_and_text_list.append((None, extra_arg))
# if no --names are provided, just use the args without a name.
else:
name_and_text_list = [(None, x) for x in args]
# Convert the plaintext text objects to bytestrings and collect
for name_and_text in name_and_text_list:
name, plaintext = name_and_text
if plaintext == '':
raise AnsibleOptionsError('The plaintext provided from the command line args was empty, not encrypting')
b_plaintext = to_bytes(plaintext)
b_plaintext_list.append((b_plaintext, self.FROM_ARGS, name))
# TODO: specify vault_id per string?
# Format the encrypted strings and any corresponding stderr output
outputs = self._format_output_vault_strings(b_plaintext_list, vault_id=self.encrypt_vault_id)
b_outs = []
for output in outputs:
err = output.get('err', None)
out = output.get('out', '')
if err:
sys.stderr.write(err)
b_outs.append(to_bytes(out))
# The output must end with a newline to play nice with terminal representation.
# Refs:
# * https://stackoverflow.com/a/729795/595220
# * https://github.com/ansible/ansible/issues/78932
b_outs.append(b'')
self.editor.write_data(b'\n'.join(b_outs), context.CLIARGS['output_file'] or '-')
if sys.stdout.isatty():
display.display("Encryption successful", stderr=True)
# TODO: offer block or string ala eyaml
def _format_output_vault_strings(self, b_plaintext_list, vault_id=None):
# If we are only showing one item in the output, we don't need to included commented
# delimiters in the text
show_delimiter = False
if len(b_plaintext_list) > 1:
show_delimiter = True
# list of dicts {'out': '', 'err': ''}
output = []
# Encrypt the plaintext, and format it into a yaml block that can be pasted into a playbook.
# For more than one input, show some differentiating info in the stderr output so we can tell them
# apart. If we have a var name, we include that in the yaml
for index, b_plaintext_info in enumerate(b_plaintext_list):
# (the text itself, which input it came from, its name)
b_plaintext, src, name = b_plaintext_info
b_ciphertext = self.editor.encrypt_bytes(b_plaintext, self.encrypt_secret, vault_id=vault_id)
# block formatting
yaml_text = self.format_ciphertext_yaml(b_ciphertext, name=name)
err_msg = None
if show_delimiter:
human_index = index + 1
if name:
err_msg = '# The encrypted version of variable ("%s", the string #%d from %s).\n' % (name, human_index, src)
else:
err_msg = '# The encrypted version of the string #%d from %s.)\n' % (human_index, src)
output.append({'out': yaml_text, 'err': err_msg})
return output
def execute_decrypt(self):
""" decrypt the supplied file using the provided vault secret """
if not context.CLIARGS['args'] and sys.stdin.isatty():
display.display("Reading ciphertext input from stdin", stderr=True)
for f in context.CLIARGS['args'] or ['-']:
self.editor.decrypt_file(f, output_file=context.CLIARGS['output_file'])
if sys.stdout.isatty():
display.display("Decryption successful", stderr=True)
def execute_create(self):
""" create and open a file in an editor that will be encrypted with the provided vault secret when closed"""
if len(context.CLIARGS['args']) != 1:
raise AnsibleOptionsError("ansible-vault create can take only one filename argument")
if sys.stdout.isatty() or context.CLIARGS['skip_tty_check']:
self.editor.create_file(context.CLIARGS['args'][0], self.encrypt_secret,
vault_id=self.encrypt_vault_id)
else:
raise AnsibleOptionsError("not a tty, editor cannot be opened")
def execute_edit(self):
""" open and decrypt an existing vaulted file in an editor, that will be encrypted again when closed"""
for f in context.CLIARGS['args']:
self.editor.edit_file(f)
def execute_view(self):
""" open, decrypt and view an existing vaulted file using a pager using the supplied vault secret """
for f in context.CLIARGS['args']:
# Note: vault should return byte strings because it could encrypt
# and decrypt binary files. We are responsible for changing it to
# unicode here because we are displaying it and therefore can make
# the decision that the display doesn't have to be precisely what
# the input was (leave that to decrypt instead)
plaintext = self.editor.plaintext(f)
self.pager(to_text(plaintext))
def execute_rekey(self):
""" re-encrypt a vaulted file with a new secret, the previous secret is required """
for f in context.CLIARGS['args']:
# FIXME: plumb in vault_id, use the default new_vault_secret for now
self.editor.rekey_file(f, self.new_encrypt_secret,
self.new_encrypt_vault_id)
display.display("Rekey successful", stderr=True)
def main(args=None):
VaultCLI.cli_executor(args)
if __name__ == '__main__':
main()
ansible_core-2.19.0b4/lib/ansible/collections/ 0000755 0000000 0000000 00000000000 15010426755 017722 5 ustar 00root root ansible_core-2.19.0b4/lib/ansible/collections/__init__.py 0000644 0000000 0000000 00000000000 15010426755 022021 0 ustar 00root root ansible_core-2.19.0b4/lib/ansible/collections/list.py 0000644 0000000 0000000 00000005471 15010426755 021256 0 ustar 00root root # (c) 2019 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import annotations
from ansible.errors import AnsibleError
from ansible.cli.galaxy import with_collection_artifacts_manager
from ansible.galaxy.collection import find_existing_collections
from ansible.module_utils.common.text.converters import to_bytes
from ansible.utils.collection_loader._collection_finder import _get_collection_name_from_path
from ansible.utils.display import Display
display = Display()
@with_collection_artifacts_manager
def list_collections(coll_filter=None, search_paths=None, dedupe=True, artifacts_manager=None):
collections = {}
for candidate in list_collection_dirs(search_paths=search_paths, coll_filter=coll_filter, artifacts_manager=artifacts_manager, dedupe=dedupe):
collection = _get_collection_name_from_path(candidate)
collections[collection] = candidate
return collections
@with_collection_artifacts_manager
def list_collection_dirs(search_paths=None, coll_filter=None, artifacts_manager=None, dedupe=True):
"""
Return paths for the specific collections found in passed or configured search paths
:param search_paths: list of text-string paths, if none load default config
:param coll_filter: limit collections to just the specific namespace or collection, if None all are returned
:return: list of collection directory paths
"""
namespace_filter = None
collection_filter = None
has_pure_namespace_filter = False # whether at least one coll_filter is a namespace-only filter
if coll_filter is not None:
if isinstance(coll_filter, str):
coll_filter = [coll_filter]
namespace_filter = set()
for coll_name in coll_filter:
if '.' in coll_name:
try:
namespace, collection = coll_name.split('.')
except ValueError:
raise AnsibleError("Invalid collection pattern supplied: %s" % coll_name)
namespace_filter.add(namespace)
if not has_pure_namespace_filter:
if collection_filter is None:
collection_filter = []
collection_filter.append(collection)
else:
namespace_filter.add(coll_name)
has_pure_namespace_filter = True
collection_filter = None
namespace_filter = sorted(namespace_filter)
for req in find_existing_collections(search_paths, artifacts_manager, namespace_filter=namespace_filter,
collection_filter=collection_filter, dedupe=dedupe):
if not has_pure_namespace_filter and coll_filter is not None and req.fqcn not in coll_filter:
continue
yield to_bytes(req.src)
ansible_core-2.19.0b4/lib/ansible/compat/ 0000755 0000000 0000000 00000000000 15010426755 016667 5 ustar 00root root ansible_core-2.19.0b4/lib/ansible/compat/__init__.py 0000644 0000000 0000000 00000001752 15010426755 021005 0 ustar 00root root # (c) 2014, Toshio Kuratomi
#
# 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 .
"""
Compat library for ansible. This contains compatibility definitions for older python
When we need to import a module differently depending on python version, do it
here. Then in the code we can simply import from compat in order to get what we want.
"""
from __future__ import annotations
ansible_core-2.19.0b4/lib/ansible/compat/importlib_resources.py 0000644 0000000 0000000 00000001074 15010426755 023336 0 ustar 00root root # Copyright: Contributors to the Ansible project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import annotations
import sys
HAS_IMPORTLIB_RESOURCES = False
if sys.version_info < (3, 10):
try:
from importlib_resources import files # type: ignore[import] # pylint: disable=unused-import
except ImportError:
files = None # type: ignore[assignment]
else:
HAS_IMPORTLIB_RESOURCES = True
else:
from importlib.resources import files
HAS_IMPORTLIB_RESOURCES = True
ansible_core-2.19.0b4/lib/ansible/config/ 0000755 0000000 0000000 00000000000 15010426755 016651 5 ustar 00root root ansible_core-2.19.0b4/lib/ansible/config/__init__.py 0000644 0000000 0000000 00000000000 15010426755 020750 0 ustar 00root root ansible_core-2.19.0b4/lib/ansible/config/ansible_builtin_runtime.yml 0000644 0000000 0000000 00001336414 15010426755 024316 0 ustar 00root root # Copyright (c) 2020 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
plugin_routing:
connection:
# test entries
redirected_local:
redirect: ansible.builtin.local
buildah:
redirect: containers.podman.buildah
podman:
redirect: containers.podman.podman
aws_ssm:
redirect: community.aws.aws_ssm
chroot:
redirect: community.general.chroot
docker:
redirect: community.docker.docker
funcd:
redirect: community.general.funcd
iocage:
redirect: community.general.iocage
jail:
redirect: community.general.jail
kubectl:
redirect: kubernetes.core.kubectl
libvirt_lxc:
redirect: community.libvirt.libvirt_lxc
lxc:
redirect: community.general.lxc
lxd:
redirect: community.general.lxd
oc:
redirect: community.okd.oc
qubes:
redirect: community.general.qubes
saltstack:
redirect: community.general.saltstack
zone:
redirect: community.general.zone
vmware_tools:
redirect: community.vmware.vmware_tools
httpapi:
redirect: ansible.netcommon.httpapi
napalm:
redirect: ansible.netcommon.napalm
netconf:
redirect: ansible.netcommon.netconf
network_cli:
redirect: ansible.netcommon.network_cli
persistent:
redirect: ansible.netcommon.persistent
modules:
# test entry
formerly_core_ping:
redirect: testns.testcoll.ping
# test entry
uses_redirected_action:
redirect: ansible.builtin.ping
podman_container_info:
redirect: containers.podman.podman_container_info
podman_image_info:
redirect: containers.podman.podman_image_info
podman_image:
redirect: containers.podman.podman_image
podman_volume_info:
redirect: containers.podman.podman_volume_info
frr_facts:
redirect: frr.frr.frr_facts
frr_bgp:
redirect: frr.frr.frr_bgp
apt_repo:
redirect: community.general.apt_repo
aws_acm_facts:
redirect: community.aws.aws_acm_facts
aws_kms_facts:
redirect: community.aws.aws_kms_facts
aws_region_facts:
redirect: community.aws.aws_region_facts
aws_s3_bucket_facts:
redirect: community.aws.aws_s3_bucket_facts
aws_sgw_facts:
redirect: community.aws.aws_sgw_facts
aws_waf_facts:
redirect: community.aws.aws_waf_facts
cloudfront_facts:
redirect: community.aws.cloudfront_facts
cloudwatchlogs_log_group_facts:
redirect: community.aws.cloudwatchlogs_log_group_facts
ec2_asg_facts:
redirect: community.aws.ec2_asg_facts
ec2_customer_gateway_facts:
redirect: community.aws.ec2_customer_gateway_facts
ec2_instance_facts:
redirect: community.aws.ec2_instance_facts
ec2_eip_facts:
redirect: community.aws.ec2_eip_facts
ec2_elb_facts:
redirect: community.aws.ec2_elb_facts
ec2_lc_facts:
redirect: community.aws.ec2_lc_facts
ec2_placement_group_facts:
redirect: community.aws.ec2_placement_group_facts
ec2_vpc_endpoint_facts:
redirect: community.aws.ec2_vpc_endpoint_facts
ec2_vpc_igw_facts:
redirect: community.aws.ec2_vpc_igw_facts
ec2_vpc_nacl_facts:
redirect: community.aws.ec2_vpc_nacl_facts
ec2_vpc_nat_gateway_facts:
redirect: community.aws.ec2_vpc_nat_gateway_facts
ec2_vpc_peering_facts:
redirect: community.aws.ec2_vpc_peering_facts
ec2_vpc_route_table_facts:
redirect: community.aws.ec2_vpc_route_table_facts
ec2_vpc_vgw_facts:
redirect: community.aws.ec2_vpc_vgw_facts
ec2_vpc_vpn_facts:
redirect: community.aws.ec2_vpc_vpn_facts
ecs_service_facts:
redirect: community.aws.ecs_service_facts
ecs_taskdefinition_facts:
redirect: community.aws.ecs_taskdefinition_facts
efs_facts:
redirect: community.aws.efs_facts
elasticache_facts:
redirect: community.aws.elasticache_facts
elb_application_lb_facts:
redirect: community.aws.elb_application_lb_facts
elb_classic_lb_facts:
redirect: community.aws.elb_classic_lb_facts
elb_target_facts:
redirect: community.aws.elb_target_facts
elb_target_group_facts:
redirect: community.aws.elb_target_group_facts
iam_cert_facts:
redirect: community.aws.iam_cert_facts
iam_mfa_device_facts:
redirect: community.aws.iam_mfa_device_facts
iam_role_facts:
redirect: community.aws.iam_role_facts
iam_server_certificate_facts:
redirect: community.aws.iam_server_certificate_facts
lambda_facts:
redirect: community.aws.lambda_facts
rds_instance_facts:
redirect: community.aws.rds_instance_facts
rds_snapshot_facts:
redirect: community.aws.rds_snapshot_facts
redshift_facts:
redirect: community.aws.redshift_facts
route53_facts:
redirect: community.aws.route53_facts
aws_acm:
redirect: community.aws.aws_acm
aws_acm_info:
redirect: community.aws.aws_acm_info
aws_api_gateway:
redirect: community.aws.aws_api_gateway
aws_application_scaling_policy:
redirect: community.aws.aws_application_scaling_policy
aws_batch_compute_environment:
redirect: community.aws.aws_batch_compute_environment
aws_batch_job_definition:
redirect: community.aws.aws_batch_job_definition
aws_batch_job_queue:
redirect: community.aws.aws_batch_job_queue
aws_codebuild:
redirect: community.aws.aws_codebuild
aws_codecommit:
redirect: community.aws.aws_codecommit
aws_codepipeline:
redirect: community.aws.aws_codepipeline
aws_config_aggregation_authorization:
redirect: community.aws.aws_config_aggregation_authorization
aws_config_aggregator:
redirect: community.aws.aws_config_aggregator
aws_config_delivery_channel:
redirect: community.aws.aws_config_delivery_channel
aws_config_recorder:
redirect: community.aws.aws_config_recorder
aws_config_rule:
redirect: community.aws.aws_config_rule
aws_direct_connect_connection:
redirect: community.aws.aws_direct_connect_connection
aws_direct_connect_gateway:
redirect: community.aws.aws_direct_connect_gateway
aws_direct_connect_link_aggregation_group:
redirect: community.aws.aws_direct_connect_link_aggregation_group
aws_direct_connect_virtual_interface:
redirect: community.aws.aws_direct_connect_virtual_interface
aws_eks_cluster:
redirect: community.aws.aws_eks_cluster
aws_elasticbeanstalk_app:
redirect: community.aws.aws_elasticbeanstalk_app
aws_glue_connection:
redirect: community.aws.aws_glue_connection
aws_glue_job:
redirect: community.aws.aws_glue_job
aws_inspector_target:
redirect: community.aws.aws_inspector_target
aws_kms:
redirect: community.aws.aws_kms
aws_kms_info:
redirect: community.aws.aws_kms_info
aws_region_info:
redirect: community.aws.aws_region_info
aws_s3_bucket_info:
redirect: community.aws.aws_s3_bucket_info
aws_s3_cors:
redirect: community.aws.aws_s3_cors
aws_secret:
redirect: community.aws.aws_secret
aws_ses_identity:
redirect: community.aws.aws_ses_identity
aws_ses_identity_policy:
redirect: community.aws.aws_ses_identity_policy
aws_ses_rule_set:
redirect: community.aws.aws_ses_rule_set
aws_sgw_info:
redirect: community.aws.aws_sgw_info
aws_ssm_parameter_store:
redirect: community.aws.aws_ssm_parameter_store
aws_step_functions_state_machine:
redirect: community.aws.aws_step_functions_state_machine
aws_step_functions_state_machine_execution:
redirect: community.aws.aws_step_functions_state_machine_execution
aws_waf_condition:
redirect: community.aws.aws_waf_condition
aws_waf_info:
redirect: community.aws.aws_waf_info
aws_waf_rule:
redirect: community.aws.aws_waf_rule
aws_waf_web_acl:
redirect: community.aws.aws_waf_web_acl
cloudformation_stack_set:
redirect: community.aws.cloudformation_stack_set
cloudformation_exports_info:
redirect: community.aws.cloudformation_exports_info
cloudfront_distribution:
redirect: community.aws.cloudfront_distribution
cloudfront_info:
redirect: community.aws.cloudfront_info
cloudfront_invalidation:
redirect: community.aws.cloudfront_invalidation
cloudfront_origin_access_identity:
redirect: community.aws.cloudfront_origin_access_identity
cloudtrail:
redirect: community.aws.cloudtrail
cloudwatchevent_rule:
redirect: community.aws.cloudwatchevent_rule
cloudwatchlogs_log_group:
redirect: community.aws.cloudwatchlogs_log_group
cloudwatchlogs_log_group_info:
redirect: community.aws.cloudwatchlogs_log_group_info
cloudwatchlogs_log_group_metric_filter:
redirect: community.aws.cloudwatchlogs_log_group_metric_filter
data_pipeline:
redirect: community.aws.data_pipeline
dms_endpoint:
redirect: community.aws.dms_endpoint
dms_replication_subnet_group:
redirect: community.aws.dms_replication_subnet_group
dynamodb_table:
redirect: community.aws.dynamodb_table
dynamodb_ttl:
redirect: community.aws.dynamodb_ttl
ec2_ami_copy:
redirect: community.aws.ec2_ami_copy
ec2_asg:
redirect: community.aws.ec2_asg
ec2_asg_info:
redirect: community.aws.ec2_asg_info
ec2_asg_lifecycle_hook:
redirect: community.aws.ec2_asg_lifecycle_hook
ec2_customer_gateway:
redirect: community.aws.ec2_customer_gateway
ec2_customer_gateway_info:
redirect: community.aws.ec2_customer_gateway_info
ec2_eip:
redirect: community.aws.ec2_eip
ec2_eip_info:
redirect: community.aws.ec2_eip_info
ec2_elb:
redirect: community.aws.ec2_elb
ec2_elb_info:
redirect: community.aws.ec2_elb_info
ec2_instance:
redirect: community.aws.ec2_instance
ec2_instance_info:
redirect: community.aws.ec2_instance_info
ec2_launch_template:
redirect: community.aws.ec2_launch_template
ec2_lc:
redirect: community.aws.ec2_lc
ec2_lc_find:
redirect: community.aws.ec2_lc_find
ec2_lc_info:
redirect: community.aws.ec2_lc_info
ec2_metric_alarm:
redirect: community.aws.ec2_metric_alarm
ec2_placement_group:
redirect: community.aws.ec2_placement_group
ec2_placement_group_info:
redirect: community.aws.ec2_placement_group_info
ec2_scaling_policy:
redirect: community.aws.ec2_scaling_policy
ec2_snapshot_copy:
redirect: community.aws.ec2_snapshot_copy
ec2_transit_gateway:
redirect: community.aws.ec2_transit_gateway
ec2_transit_gateway_info:
redirect: community.aws.ec2_transit_gateway_info
ec2_vpc_egress_igw:
redirect: community.aws.ec2_vpc_egress_igw
ec2_vpc_endpoint:
redirect: community.aws.ec2_vpc_endpoint
ec2_vpc_endpoint_info:
redirect: community.aws.ec2_vpc_endpoint_info
ec2_vpc_igw:
redirect: community.aws.ec2_vpc_igw
ec2_vpc_igw_info:
redirect: community.aws.ec2_vpc_igw_info
ec2_vpc_nacl:
redirect: community.aws.ec2_vpc_nacl
ec2_vpc_nacl_info:
redirect: community.aws.ec2_vpc_nacl_info
ec2_vpc_nat_gateway:
redirect: community.aws.ec2_vpc_nat_gateway
ec2_vpc_nat_gateway_info:
redirect: community.aws.ec2_vpc_nat_gateway_info
ec2_vpc_peer:
redirect: community.aws.ec2_vpc_peer
ec2_vpc_peering_info:
redirect: community.aws.ec2_vpc_peering_info
ec2_vpc_route_table:
redirect: community.aws.ec2_vpc_route_table
ec2_vpc_route_table_info:
redirect: community.aws.ec2_vpc_route_table_info
ec2_vpc_vgw:
redirect: community.aws.ec2_vpc_vgw
ec2_vpc_vgw_info:
redirect: community.aws.ec2_vpc_vgw_info
ec2_vpc_vpn:
redirect: community.aws.ec2_vpc_vpn
ec2_vpc_vpn_info:
redirect: community.aws.ec2_vpc_vpn_info
ec2_win_password:
redirect: community.aws.ec2_win_password
ecs_attribute:
redirect: community.aws.ecs_attribute
ecs_cluster:
redirect: community.aws.ecs_cluster
ecs_ecr:
redirect: community.aws.ecs_ecr
ecs_service:
redirect: community.aws.ecs_service
ecs_service_info:
redirect: community.aws.ecs_service_info
ecs_tag:
redirect: community.aws.ecs_tag
ecs_task:
redirect: community.aws.ecs_task
ecs_taskdefinition:
redirect: community.aws.ecs_taskdefinition
ecs_taskdefinition_info:
redirect: community.aws.ecs_taskdefinition_info
efs:
redirect: community.aws.efs
efs_info:
redirect: community.aws.efs_info
elasticache:
redirect: community.aws.elasticache
elasticache_info:
redirect: community.aws.elasticache_info
elasticache_parameter_group:
redirect: community.aws.elasticache_parameter_group
elasticache_snapshot:
redirect: community.aws.elasticache_snapshot
elasticache_subnet_group:
redirect: community.aws.elasticache_subnet_group
elb_application_lb:
redirect: community.aws.elb_application_lb
elb_application_lb_info:
redirect: community.aws.elb_application_lb_info
elb_classic_lb:
redirect: community.aws.elb_classic_lb
elb_classic_lb_info:
redirect: community.aws.elb_classic_lb_info
elb_instance:
redirect: community.aws.elb_instance
elb_network_lb:
redirect: community.aws.elb_network_lb
elb_target:
redirect: community.aws.elb_target
elb_target_group:
redirect: community.aws.elb_target_group
elb_target_group_info:
redirect: community.aws.elb_target_group_info
elb_target_info:
redirect: community.aws.elb_target_info
execute_lambda:
redirect: community.aws.execute_lambda
iam:
redirect: community.aws.iam
iam_cert:
redirect: community.aws.iam_cert
iam_group:
redirect: community.aws.iam_group
iam_managed_policy:
redirect: community.aws.iam_managed_policy
iam_mfa_device_info:
redirect: community.aws.iam_mfa_device_info
iam_password_policy:
redirect: community.aws.iam_password_policy
iam_policy:
redirect: community.aws.iam_policy
iam_policy_info:
redirect: community.aws.iam_policy_info
iam_role:
redirect: community.aws.iam_role
iam_role_info:
redirect: community.aws.iam_role_info
iam_saml_federation:
redirect: community.aws.iam_saml_federation
iam_server_certificate_info:
redirect: community.aws.iam_server_certificate_info
iam_user:
redirect: community.aws.iam_user
iam_user_info:
redirect: community.aws.iam_user_info
kinesis_stream:
redirect: community.aws.kinesis_stream
lambda:
redirect: community.aws.lambda
lambda_alias:
redirect: community.aws.lambda_alias
lambda_event:
redirect: community.aws.lambda_event
lambda_info:
redirect: community.aws.lambda_info
lambda_policy:
redirect: community.aws.lambda_policy
lightsail:
redirect: community.aws.lightsail
rds:
redirect: community.aws.rds
rds_instance:
redirect: community.aws.rds_instance
rds_instance_info:
redirect: community.aws.rds_instance_info
rds_param_group:
redirect: community.aws.rds_param_group
rds_snapshot:
redirect: community.aws.rds_snapshot
rds_snapshot_info:
redirect: community.aws.rds_snapshot_info
rds_subnet_group:
redirect: community.aws.rds_subnet_group
redshift:
redirect: community.aws.redshift
redshift_cross_region_snapshots:
redirect: community.aws.redshift_cross_region_snapshots
redshift_info:
redirect: community.aws.redshift_info
redshift_subnet_group:
redirect: community.aws.redshift_subnet_group
route53:
redirect: community.aws.route53
route53_health_check:
redirect: community.aws.route53_health_check
route53_info:
redirect: community.aws.route53_info
route53_zone:
redirect: community.aws.route53_zone
s3_bucket_notification:
redirect: community.aws.s3_bucket_notification
s3_lifecycle:
redirect: community.aws.s3_lifecycle
s3_logging:
redirect: community.aws.s3_logging
s3_sync:
redirect: community.aws.s3_sync
s3_website:
redirect: community.aws.s3_website
sns:
redirect: community.aws.sns
sns_topic:
redirect: community.aws.sns_topic
sqs_queue:
redirect: community.aws.sqs_queue
sts_assume_role:
redirect: community.aws.sts_assume_role
sts_session_token:
redirect: community.aws.sts_session_token
ali_instance_facts:
redirect: community.general.ali_instance_facts
ali_instance:
redirect: community.general.ali_instance
ali_instance_info:
redirect: community.general.ali_instance_info
atomic_container:
redirect: community.general.atomic_container
atomic_host:
redirect: community.general.atomic_host
atomic_image:
redirect: community.general.atomic_image
clc_aa_policy:
redirect: community.general.clc_aa_policy
clc_alert_policy:
redirect: community.general.clc_alert_policy
clc_blueprint_package:
redirect: community.general.clc_blueprint_package
clc_firewall_policy:
redirect: community.general.clc_firewall_policy
clc_group:
redirect: community.general.clc_group
clc_loadbalancer:
redirect: community.general.clc_loadbalancer
clc_modify_server:
redirect: community.general.clc_modify_server
clc_publicip:
redirect: community.general.clc_publicip
clc_server:
redirect: community.general.clc_server
clc_server_snapshot:
redirect: community.general.clc_server_snapshot
cloudscale_floating_ip:
redirect: cloudscale_ch.cloud.floating_ip
cloudscale_server:
redirect: cloudscale_ch.cloud.server
cloudscale_server_group:
redirect: cloudscale_ch.cloud.server_group
cloudscale_volume:
redirect: cloudscale_ch.cloud.volume
cs_instance_facts:
redirect: ngine_io.cloudstack.cs_instance_info
cs_zone_facts:
redirect: ngine_io.cloudstack.cs_zone_info
cs_account:
redirect: ngine_io.cloudstack.cs_account
cs_affinitygroup:
redirect: ngine_io.cloudstack.cs_affinitygroup
cs_cluster:
redirect: ngine_io.cloudstack.cs_cluster
cs_configuration:
redirect: ngine_io.cloudstack.cs_configuration
cs_disk_offering:
redirect: ngine_io.cloudstack.cs_disk_offering
cs_domain:
redirect: ngine_io.cloudstack.cs_domain
cs_facts:
redirect: ngine_io.cloudstack.cs_facts
cs_firewall:
redirect: ngine_io.cloudstack.cs_firewall
cs_host:
redirect: ngine_io.cloudstack.cs_host
cs_image_store:
redirect: ngine_io.cloudstack.cs_image_store
cs_instance:
redirect: ngine_io.cloudstack.cs_instance
cs_instance_info:
redirect: ngine_io.cloudstack.cs_instance_info
cs_instance_nic:
redirect: ngine_io.cloudstack.cs_instance_nic
cs_instance_nic_secondaryip:
redirect: ngine_io.cloudstack.cs_instance_nic_secondaryip
cs_instance_password_reset:
redirect: ngine_io.cloudstack.cs_instance_password_reset
cs_instancegroup:
redirect: ngine_io.cloudstack.cs_instancegroup
cs_ip_address:
redirect: ngine_io.cloudstack.cs_ip_address
cs_iso:
redirect: ngine_io.cloudstack.cs_iso
cs_loadbalancer_rule:
redirect: ngine_io.cloudstack.cs_loadbalancer_rule
cs_loadbalancer_rule_member:
redirect: ngine_io.cloudstack.cs_loadbalancer_rule_member
cs_network:
redirect: ngine_io.cloudstack.cs_network
cs_network_acl:
redirect: ngine_io.cloudstack.cs_network_acl
cs_network_acl_rule:
redirect: ngine_io.cloudstack.cs_network_acl_rule
cs_network_offering:
redirect: ngine_io.cloudstack.cs_network_offering
cs_physical_network:
redirect: ngine_io.cloudstack.cs_physical_network
cs_pod:
redirect: ngine_io.cloudstack.cs_pod
cs_portforward:
redirect: ngine_io.cloudstack.cs_portforward
cs_project:
redirect: ngine_io.cloudstack.cs_project
cs_region:
redirect: ngine_io.cloudstack.cs_region
cs_resourcelimit:
redirect: ngine_io.cloudstack.cs_resourcelimit
cs_role:
redirect: ngine_io.cloudstack.cs_role
cs_role_permission:
redirect: ngine_io.cloudstack.cs_role_permission
cs_router:
redirect: ngine_io.cloudstack.cs_router
cs_securitygroup:
redirect: ngine_io.cloudstack.cs_securitygroup
cs_securitygroup_rule:
redirect: ngine_io.cloudstack.cs_securitygroup_rule
cs_service_offering:
redirect: ngine_io.cloudstack.cs_service_offering
cs_snapshot_policy:
redirect: ngine_io.cloudstack.cs_snapshot_policy
cs_sshkeypair:
redirect: ngine_io.cloudstack.cs_sshkeypair
cs_staticnat:
redirect: ngine_io.cloudstack.cs_staticnat
cs_storage_pool:
redirect: ngine_io.cloudstack.cs_storage_pool
cs_template:
redirect: ngine_io.cloudstack.cs_template
cs_traffic_type:
redirect: ngine_io.cloudstack.cs_traffic_type
cs_user:
redirect: ngine_io.cloudstack.cs_user
cs_vlan_ip_range:
redirect: ngine_io.cloudstack.cs_vlan_ip_range
cs_vmsnapshot:
redirect: ngine_io.cloudstack.cs_vmsnapshot
cs_volume:
redirect: ngine_io.cloudstack.cs_volume
cs_vpc:
redirect: ngine_io.cloudstack.cs_vpc
cs_vpc_offering:
redirect: ngine_io.cloudstack.cs_vpc_offering
cs_vpn_connection:
redirect: ngine_io.cloudstack.cs_vpn_connection
cs_vpn_customer_gateway:
redirect: ngine_io.cloudstack.cs_vpn_customer_gateway
cs_vpn_gateway:
redirect: ngine_io.cloudstack.cs_vpn_gateway
cs_zone:
redirect: ngine_io.cloudstack.cs_zone
cs_zone_info:
redirect: ngine_io.cloudstack.cs_zone_info
digital_ocean:
redirect: community.digitalocean.digital_ocean
digital_ocean_account_facts:
redirect: community.digitalocean.digital_ocean_account_facts
digital_ocean_certificate_facts:
redirect: community.digitalocean.digital_ocean_certificate_facts
digital_ocean_domain_facts:
redirect: community.digitalocean.digital_ocean_domain_facts
digital_ocean_firewall_facts:
redirect: community.digitalocean.digital_ocean_firewall_facts
digital_ocean_floating_ip_facts:
redirect: community.digitalocean.digital_ocean_floating_ip_facts
digital_ocean_image_facts:
redirect: community.digitalocean.digital_ocean_image_facts
digital_ocean_load_balancer_facts:
redirect: community.digitalocean.digital_ocean_load_balancer_facts
digital_ocean_region_facts:
redirect: community.digitalocean.digital_ocean_region_facts
digital_ocean_size_facts:
redirect: community.digitalocean.digital_ocean_size_facts
digital_ocean_snapshot_facts:
redirect: community.digitalocean.digital_ocean_snapshot_facts
digital_ocean_sshkey_facts:
redirect: community.digitalocean.digital_ocean_sshkey_facts
digital_ocean_tag_facts:
redirect: community.digitalocean.digital_ocean_tag_facts
digital_ocean_volume_facts:
redirect: community.digitalocean.digital_ocean_volume_facts
digital_ocean_account_info:
redirect: community.digitalocean.digital_ocean_account_info
digital_ocean_block_storage:
redirect: community.digitalocean.digital_ocean_block_storage
digital_ocean_certificate:
redirect: community.digitalocean.digital_ocean_certificate
digital_ocean_certificate_info:
redirect: community.digitalocean.digital_ocean_certificate_info
digital_ocean_domain:
redirect: community.digitalocean.digital_ocean_domain
digital_ocean_domain_info:
redirect: community.digitalocean.digital_ocean_domain_info
digital_ocean_droplet:
redirect: community.digitalocean.digital_ocean_droplet
digital_ocean_firewall_info:
redirect: community.digitalocean.digital_ocean_firewall_info
digital_ocean_floating_ip:
redirect: community.digitalocean.digital_ocean_floating_ip
digital_ocean_floating_ip_info:
redirect: community.digitalocean.digital_ocean_floating_ip_info
digital_ocean_image_info:
redirect: community.digitalocean.digital_ocean_image_info
digital_ocean_load_balancer_info:
redirect: community.digitalocean.digital_ocean_load_balancer_info
digital_ocean_region_info:
redirect: community.digitalocean.digital_ocean_region_info
digital_ocean_size_info:
redirect: community.digitalocean.digital_ocean_size_info
digital_ocean_snapshot_info:
redirect: community.digitalocean.digital_ocean_snapshot_info
digital_ocean_sshkey:
redirect: community.digitalocean.digital_ocean_sshkey
digital_ocean_sshkey_info:
redirect: community.digitalocean.digital_ocean_sshkey_info
digital_ocean_tag:
redirect: community.digitalocean.digital_ocean_tag
digital_ocean_tag_info:
redirect: community.digitalocean.digital_ocean_tag_info
digital_ocean_volume_info:
redirect: community.digitalocean.digital_ocean_volume_info
dimensiondata_network:
redirect: community.general.dimensiondata_network
dimensiondata_vlan:
redirect: community.general.dimensiondata_vlan
docker_image_facts:
redirect: community.general.docker_image_facts
docker_service:
redirect: community.general.docker_service
docker_compose:
redirect: community.docker.docker_compose
docker_config:
redirect: community.docker.docker_config
docker_container:
redirect: community.docker.docker_container
docker_container_info:
redirect: community.docker.docker_container_info
docker_host_info:
redirect: community.docker.docker_host_info
docker_image:
redirect: community.docker.docker_image
docker_image_info:
redirect: community.docker.docker_image_info
docker_login:
redirect: community.docker.docker_login
docker_network:
redirect: community.docker.docker_network
docker_network_info:
redirect: community.docker.docker_network_info
docker_node:
redirect: community.docker.docker_node
docker_node_info:
redirect: community.docker.docker_node_info
docker_prune:
redirect: community.docker.docker_prune
docker_secret:
redirect: community.docker.docker_secret
docker_stack:
redirect: community.docker.docker_stack
docker_swarm:
redirect: community.docker.docker_swarm
docker_swarm_info:
redirect: community.docker.docker_swarm_info
docker_swarm_service:
redirect: community.docker.docker_swarm_service
docker_swarm_service_info:
redirect: community.docker.docker_swarm_service_info
docker_volume:
redirect: community.docker.docker_volume
docker_volume_info:
redirect: community.docker.docker_volume_info
gcdns_record:
redirect: community.general.gcdns_record
gcdns_zone:
redirect: community.general.gcdns_zone
gce:
redirect: community.general.gce
gcp_backend_service:
redirect: community.general.gcp_backend_service
gcp_bigquery_dataset_facts:
redirect: google.cloud.gcp_bigquery_dataset_info
gcp_bigquery_table_facts:
redirect: google.cloud.gcp_bigquery_table_info
gcp_cloudbuild_trigger_facts:
redirect: google.cloud.gcp_cloudbuild_trigger_info
gcp_compute_address_facts:
redirect: google.cloud.gcp_compute_address_info
gcp_compute_backend_bucket_facts:
redirect: google.cloud.gcp_compute_backend_bucket_info
gcp_compute_backend_service_facts:
redirect: google.cloud.gcp_compute_backend_service_info
gcp_compute_disk_facts:
redirect: google.cloud.gcp_compute_disk_info
gcp_compute_firewall_facts:
redirect: google.cloud.gcp_compute_firewall_info
gcp_compute_forwarding_rule_facts:
redirect: google.cloud.gcp_compute_forwarding_rule_info
gcp_compute_global_address_facts:
redirect: google.cloud.gcp_compute_global_address_info
gcp_compute_global_forwarding_rule_facts:
redirect: google.cloud.gcp_compute_global_forwarding_rule_info
gcp_compute_health_check_facts:
redirect: google.cloud.gcp_compute_health_check_info
gcp_compute_http_health_check_facts:
redirect: google.cloud.gcp_compute_http_health_check_info
gcp_compute_https_health_check_facts:
redirect: google.cloud.gcp_compute_https_health_check_info
gcp_compute_image_facts:
redirect: google.cloud.gcp_compute_image_info
gcp_compute_instance_facts:
redirect: google.cloud.gcp_compute_instance_info
gcp_compute_instance_group_facts:
redirect: google.cloud.gcp_compute_instance_group_info
gcp_compute_instance_group_manager_facts:
redirect: google.cloud.gcp_compute_instance_group_manager_info
gcp_compute_instance_template_facts:
redirect: google.cloud.gcp_compute_instance_template_info
gcp_compute_interconnect_attachment_facts:
redirect: google.cloud.gcp_compute_interconnect_attachment_info
gcp_compute_network_facts:
redirect: google.cloud.gcp_compute_network_info
gcp_compute_region_disk_facts:
redirect: google.cloud.gcp_compute_region_disk_info
gcp_compute_route_facts:
redirect: google.cloud.gcp_compute_route_info
gcp_compute_router_facts:
redirect: google.cloud.gcp_compute_router_info
gcp_compute_ssl_certificate_facts:
redirect: google.cloud.gcp_compute_ssl_certificate_info
gcp_compute_ssl_policy_facts:
redirect: google.cloud.gcp_compute_ssl_policy_info
gcp_compute_subnetwork_facts:
redirect: google.cloud.gcp_compute_subnetwork_info
gcp_compute_target_http_proxy_facts:
redirect: google.cloud.gcp_compute_target_http_proxy_info
gcp_compute_target_https_proxy_facts:
redirect: google.cloud.gcp_compute_target_https_proxy_info
gcp_compute_target_pool_facts:
redirect: google.cloud.gcp_compute_target_pool_info
gcp_compute_target_ssl_proxy_facts:
redirect: google.cloud.gcp_compute_target_ssl_proxy_info
gcp_compute_target_tcp_proxy_facts:
redirect: google.cloud.gcp_compute_target_tcp_proxy_info
gcp_compute_target_vpn_gateway_facts:
redirect: google.cloud.gcp_compute_target_vpn_gateway_info
gcp_compute_url_map_facts:
redirect: google.cloud.gcp_compute_url_map_info
gcp_compute_vpn_tunnel_facts:
redirect: google.cloud.gcp_compute_vpn_tunnel_info
gcp_container_cluster_facts:
redirect: google.cloud.gcp_container_cluster_info
gcp_container_node_pool_facts:
redirect: google.cloud.gcp_container_node_pool_info
gcp_dns_managed_zone_facts:
redirect: google.cloud.gcp_dns_managed_zone_info
gcp_dns_resource_record_set_facts:
redirect: google.cloud.gcp_dns_resource_record_set_info
gcp_forwarding_rule:
redirect: community.general.gcp_forwarding_rule
gcp_healthcheck:
redirect: community.general.gcp_healthcheck
gcp_iam_role_facts:
redirect: google.cloud.gcp_iam_role_info
gcp_iam_service_account_facts:
redirect: google.cloud.gcp_iam_service_account_info
gcp_pubsub_subscription_facts:
redirect: google.cloud.gcp_pubsub_subscription_info
gcp_pubsub_topic_facts:
redirect: google.cloud.gcp_pubsub_topic_info
gcp_redis_instance_facts:
redirect: google.cloud.gcp_redis_instance_info
gcp_resourcemanager_project_facts:
redirect: google.cloud.gcp_resourcemanager_project_info
gcp_sourcerepo_repository_facts:
redirect: google.cloud.gcp_sourcerepo_repository_info
gcp_spanner_database_facts:
redirect: google.cloud.gcp_spanner_database_info
gcp_spanner_instance_facts:
redirect: google.cloud.gcp_spanner_instance_info
gcp_sql_database_facts:
redirect: google.cloud.gcp_sql_database_info
gcp_sql_instance_facts:
redirect: google.cloud.gcp_sql_instance_info
gcp_sql_user_facts:
redirect: google.cloud.gcp_sql_user_info
gcp_target_proxy:
redirect: community.general.gcp_target_proxy
gcp_tpu_node_facts:
redirect: google.cloud.gcp_tpu_node_info
gcp_url_map:
redirect: community.general.gcp_url_map
gcpubsub_facts:
redirect: community.general.gcpubsub_facts
gcspanner:
redirect: community.general.gcspanner
gc_storage:
redirect: community.google.gc_storage
gce_eip:
redirect: community.google.gce_eip
gce_img:
redirect: community.google.gce_img
gce_instance_template:
redirect: community.google.gce_instance_template
gce_labels:
redirect: community.google.gce_labels
gce_lb:
redirect: community.google.gce_lb
gce_mig:
redirect: community.google.gce_mig
gce_net:
redirect: community.google.gce_net
gce_pd:
redirect: community.google.gce_pd
gce_snapshot:
redirect: community.google.gce_snapshot
gce_tag:
redirect: community.google.gce_tag
gcpubsub:
redirect: community.google.gcpubsub
gcpubsub_info:
redirect: community.google.gcpubsub_info
heroku_collaborator:
redirect: community.general.heroku_collaborator
hwc_ecs_instance:
redirect: community.general.hwc_ecs_instance
hwc_evs_disk:
redirect: community.general.hwc_evs_disk
hwc_network_vpc:
redirect: community.general.hwc_network_vpc
hwc_smn_topic:
redirect: community.general.hwc_smn_topic
hwc_vpc_eip:
redirect: community.general.hwc_vpc_eip
hwc_vpc_peering_connect:
redirect: community.general.hwc_vpc_peering_connect
hwc_vpc_port:
redirect: community.general.hwc_vpc_port
hwc_vpc_private_ip:
redirect: community.general.hwc_vpc_private_ip
hwc_vpc_route:
redirect: community.general.hwc_vpc_route
hwc_vpc_security_group:
redirect: community.general.hwc_vpc_security_group
hwc_vpc_security_group_rule:
redirect: community.general.hwc_vpc_security_group_rule
hwc_vpc_subnet:
redirect: community.general.hwc_vpc_subnet
kubevirt_cdi_upload:
redirect: community.kubevirt.kubevirt_cdi_upload
kubevirt_preset:
redirect: community.kubevirt.kubevirt_preset
kubevirt_pvc:
redirect: community.kubevirt.kubevirt_pvc
kubevirt_rs:
redirect: community.kubevirt.kubevirt_rs
kubevirt_template:
redirect: community.kubevirt.kubevirt_template
kubevirt_vm:
redirect: community.kubevirt.kubevirt_vm
linode:
redirect: community.general.linode
linode_v4:
redirect: community.general.linode_v4
lxc_container:
redirect: community.general.lxc_container
lxd_container:
redirect: community.general.lxd_container
lxd_profile:
redirect: community.general.lxd_profile
memset_memstore_facts:
redirect: community.general.memset_memstore_facts
memset_server_facts:
redirect: community.general.memset_server_facts
memset_dns_reload:
redirect: community.general.memset_dns_reload
memset_memstore_info:
redirect: community.general.memset_memstore_info
memset_server_info:
redirect: community.general.memset_server_info
memset_zone:
redirect: community.general.memset_zone
memset_zone_domain:
redirect: community.general.memset_zone_domain
memset_zone_record:
redirect: community.general.memset_zone_record
cloud_init_data_facts:
redirect: community.general.cloud_init_data_facts
helm:
redirect: community.general.helm
ovirt:
redirect: community.general.ovirt
proxmox:
redirect: community.general.proxmox
proxmox_kvm:
redirect: community.general.proxmox_kvm
proxmox_template:
redirect: community.general.proxmox_template
rhevm:
redirect: community.general.rhevm
serverless:
redirect: community.general.serverless
terraform:
redirect: community.general.terraform
virt:
redirect: community.libvirt.virt
virt_net:
redirect: community.libvirt.virt_net
virt_pool:
redirect: community.libvirt.virt_pool
xenserver_facts:
redirect: community.general.xenserver_facts
oneandone_firewall_policy:
redirect: community.general.oneandone_firewall_policy
oneandone_load_balancer:
redirect: community.general.oneandone_load_balancer
oneandone_monitoring_policy:
redirect: community.general.oneandone_monitoring_policy
oneandone_private_network:
redirect: community.general.oneandone_private_network
oneandone_public_ip:
redirect: community.general.oneandone_public_ip
oneandone_server:
redirect: community.general.oneandone_server
online_server_facts:
redirect: community.general.online_server_facts
online_user_facts:
redirect: community.general.online_user_facts
online_server_info:
redirect: community.general.online_server_info
online_user_info:
redirect: community.general.online_user_info
one_image_facts:
redirect: community.general.one_image_facts
one_host:
redirect: community.general.one_host
one_image:
redirect: community.general.one_image
one_image_info:
redirect: community.general.one_image_info
one_service:
redirect: community.general.one_service
one_vm:
redirect: community.general.one_vm
os_flavor_facts:
redirect: openstack.cloud.os_flavor_info
os_image_facts:
redirect: openstack.cloud.os_image_info
os_keystone_domain_facts:
redirect: openstack.cloud.os_keystone_domain_info
os_networks_facts:
redirect: openstack.cloud.os_networks_info
os_port_facts:
redirect: openstack.cloud.os_port_info
os_project_facts:
redirect: openstack.cloud.os_project_info
os_server_facts:
redirect: openstack.cloud.os_server_info
os_subnets_facts:
redirect: openstack.cloud.os_subnets_info
os_user_facts:
redirect: openstack.cloud.os_user_info
oci_vcn:
redirect: community.general.oci_vcn
ovh_ip_failover:
redirect: community.general.ovh_ip_failover
ovh_ip_loadbalancing_backend:
redirect: community.general.ovh_ip_loadbalancing_backend
ovh_monthly_billing:
redirect: community.general.ovh_monthly_billing
ovirt_affinity_label_facts:
redirect: community.general.ovirt_affinity_label_facts
ovirt_api_facts:
redirect: community.general.ovirt_api_facts
ovirt_cluster_facts:
redirect: community.general.ovirt_cluster_facts
ovirt_datacenter_facts:
redirect: community.general.ovirt_datacenter_facts
ovirt_disk_facts:
redirect: community.general.ovirt_disk_facts
ovirt_event_facts:
redirect: community.general.ovirt_event_facts
ovirt_external_provider_facts:
redirect: community.general.ovirt_external_provider_facts
ovirt_group_facts:
redirect: community.general.ovirt_group_facts
ovirt_host_facts:
redirect: community.general.ovirt_host_facts
ovirt_host_storage_facts:
redirect: community.general.ovirt_host_storage_facts
ovirt_network_facts:
redirect: community.general.ovirt_network_facts
ovirt_nic_facts:
redirect: community.general.ovirt_nic_facts
ovirt_permission_facts:
redirect: community.general.ovirt_permission_facts
ovirt_quota_facts:
redirect: community.general.ovirt_quota_facts
ovirt_scheduling_policy_facts:
redirect: community.general.ovirt_scheduling_policy_facts
ovirt_snapshot_facts:
redirect: community.general.ovirt_snapshot_facts
ovirt_storage_domain_facts:
redirect: community.general.ovirt_storage_domain_facts
ovirt_storage_template_facts:
redirect: community.general.ovirt_storage_template_facts
ovirt_storage_vm_facts:
redirect: community.general.ovirt_storage_vm_facts
ovirt_tag_facts:
redirect: community.general.ovirt_tag_facts
ovirt_template_facts:
redirect: community.general.ovirt_template_facts
ovirt_user_facts:
redirect: community.general.ovirt_user_facts
ovirt_vm_facts:
redirect: community.general.ovirt_vm_facts
ovirt_vmpool_facts:
redirect: community.general.ovirt_vmpool_facts
packet_device:
redirect: community.general.packet_device
packet_ip_subnet:
redirect: community.general.packet_ip_subnet
packet_project:
redirect: community.general.packet_project
packet_sshkey:
redirect: community.general.packet_sshkey
packet_volume:
redirect: community.general.packet_volume
packet_volume_attachment:
redirect: community.general.packet_volume_attachment
profitbricks:
redirect: community.general.profitbricks
profitbricks_datacenter:
redirect: community.general.profitbricks_datacenter
profitbricks_nic:
redirect: community.general.profitbricks_nic
profitbricks_volume:
redirect: community.general.profitbricks_volume
profitbricks_volume_attachments:
redirect: community.general.profitbricks_volume_attachments
pubnub_blocks:
redirect: community.general.pubnub_blocks
rax:
redirect: community.general.rax
rax_cbs:
redirect: community.general.rax_cbs
rax_cbs_attachments:
redirect: community.general.rax_cbs_attachments
rax_cdb:
redirect: community.general.rax_cdb
rax_cdb_database:
redirect: community.general.rax_cdb_database
rax_cdb_user:
redirect: community.general.rax_cdb_user
rax_clb:
redirect: community.general.rax_clb
rax_clb_nodes:
redirect: community.general.rax_clb_nodes
rax_clb_ssl:
redirect: community.general.rax_clb_ssl
rax_dns:
redirect: community.general.rax_dns
rax_dns_record:
redirect: community.general.rax_dns_record
rax_facts:
redirect: community.general.rax_facts
rax_files:
redirect: community.general.rax_files
rax_files_objects:
redirect: community.general.rax_files_objects
rax_identity:
redirect: community.general.rax_identity
rax_keypair:
redirect: community.general.rax_keypair
rax_meta:
redirect: community.general.rax_meta
rax_mon_alarm:
redirect: community.general.rax_mon_alarm
rax_mon_check:
redirect: community.general.rax_mon_check
rax_mon_entity:
redirect: community.general.rax_mon_entity
rax_mon_notification:
redirect: community.general.rax_mon_notification
rax_mon_notification_plan:
redirect: community.general.rax_mon_notification_plan
rax_network:
redirect: community.general.rax_network
rax_queue:
redirect: community.general.rax_queue
rax_scaling_group:
redirect: community.general.rax_scaling_group
rax_scaling_policy:
redirect: community.general.rax_scaling_policy
scaleway_image_facts:
redirect: community.general.scaleway_image_facts
scaleway_ip_facts:
redirect: community.general.scaleway_ip_facts
scaleway_organization_facts:
redirect: community.general.scaleway_organization_facts
scaleway_security_group_facts:
redirect: community.general.scaleway_security_group_facts
scaleway_server_facts:
redirect: community.general.scaleway_server_facts
scaleway_snapshot_facts:
redirect: community.general.scaleway_snapshot_facts
scaleway_volume_facts:
redirect: community.general.scaleway_volume_facts
scaleway_compute:
redirect: community.general.scaleway_compute
scaleway_image_info:
redirect: community.general.scaleway_image_info
scaleway_ip:
redirect: community.general.scaleway_ip
scaleway_ip_info:
redirect: community.general.scaleway_ip_info
scaleway_lb:
redirect: community.general.scaleway_lb
scaleway_organization_info:
redirect: community.general.scaleway_organization_info
scaleway_security_group:
redirect: community.general.scaleway_security_group
scaleway_security_group_info:
redirect: community.general.scaleway_security_group_info
scaleway_security_group_rule:
redirect: community.general.scaleway_security_group_rule
scaleway_server_info:
redirect: community.general.scaleway_server_info
scaleway_snapshot_info:
redirect: community.general.scaleway_snapshot_info
scaleway_sshkey:
redirect: community.general.scaleway_sshkey
scaleway_user_data:
redirect: community.general.scaleway_user_data
scaleway_volume:
redirect: community.general.scaleway_volume
scaleway_volume_info:
redirect: community.general.scaleway_volume_info
smartos_image_facts:
redirect: community.general.smartos_image_facts
imgadm:
redirect: community.general.imgadm
nictagadm:
redirect: community.general.nictagadm
smartos_image_info:
redirect: community.general.smartos_image_info
vmadm:
redirect: community.general.vmadm
sl_vm:
redirect: community.general.sl_vm
spotinst_aws_elastigroup:
redirect: community.general.spotinst_aws_elastigroup
udm_dns_record:
redirect: community.general.udm_dns_record
udm_dns_zone:
redirect: community.general.udm_dns_zone
udm_group:
redirect: community.general.udm_group
udm_share:
redirect: community.general.udm_share
udm_user:
redirect: community.general.udm_user
vr_account_facts:
redirect: ngine_io.vultr.vultr_account_facts
vr_dns_domain:
redirect: ngine_io.vultr.vultr_dns_domain
vr_dns_record:
redirect: ngine_io.vultr.vultr_dns_record
vr_firewall_group:
redirect: ngine_io.vultr.vultr_firewall_group
vr_firewall_rule:
redirect: ngine_io.vultr.vultr_firewall_rule
vr_server:
redirect: ngine_io.vultr.vultr_server
vr_ssh_key:
redirect: ngine_io.vultr.vultr_ssh_key
vr_startup_script:
redirect: ngine_io.vultr.vultr_startup_script
vr_user:
redirect: ngine_io.vultr.vultr_user
vultr_account_facts:
redirect: ngine_io.vultr.vultr_account_info
vultr_block_storage_facts:
redirect: ngine_io.vultr.vultr_block_storage_info
vultr_dns_domain_facts:
redirect: ngine_io.vultr.vultr_dns_domain_info
vultr_firewall_group_facts:
redirect: ngine_io.vultr.vultr_firewall_group_info
vultr_network_facts:
redirect: ngine_io.vultr.vultr_network_info
vultr_os_facts:
redirect: ngine_io.vultr.vultr_os_info
vultr_plan_facts:
redirect: ngine_io.vultr.vultr_plan_info
vultr_region_facts:
redirect: ngine_io.vultr.vultr_region_info
vultr_server_facts:
redirect: ngine_io.vultr.vultr_server_info
vultr_ssh_key_facts:
redirect: ngine_io.vultr.vultr_ssh_key_info
vultr_startup_script_facts:
redirect: ngine_io.vultr.vultr_startup_script_info
vultr_user_facts:
redirect: ngine_io.vultr.vultr_user_info
vultr_account_info:
redirect: ngine_io.vultr.vultr_account_info
vultr_block_storage:
redirect: ngine_io.vultr.vultr_block_storage
vultr_block_storage_info:
redirect: ngine_io.vultr.vultr_block_storage_info
vultr_dns_domain:
redirect: ngine_io.vultr.vultr_dns_domain
vultr_dns_domain_info:
redirect: ngine_io.vultr.vultr_dns_domain_info
vultr_dns_record:
redirect: ngine_io.vultr.vultr_dns_record
vultr_firewall_group:
redirect: ngine_io.vultr.vultr_firewall_group
vultr_firewall_group_info:
redirect: ngine_io.vultr.vultr_firewall_group_info
vultr_firewall_rule:
redirect: ngine_io.vultr.vultr_firewall_rule
vultr_network:
redirect: ngine_io.vultr.vultr_network
vultr_network_info:
redirect: ngine_io.vultr.vultr_network_info
vultr_os_info:
redirect: ngine_io.vultr.vultr_os_info
vultr_plan_info:
redirect: ngine_io.vultr.vultr_plan_info
vultr_region_info:
redirect: ngine_io.vultr.vultr_region_info
vultr_server:
redirect: ngine_io.vultr.vultr_server
vultr_server_info:
redirect: ngine_io.vultr.vultr_server_info
vultr_ssh_key:
redirect: ngine_io.vultr.vultr_ssh_key
vultr_ssh_key_info:
redirect: ngine_io.vultr.vultr_ssh_key_info
vultr_startup_script:
redirect: ngine_io.vultr.vultr_startup_script
vultr_startup_script_info:
redirect: ngine_io.vultr.vultr_startup_script_info
vultr_user:
redirect: ngine_io.vultr.vultr_user
vultr_user_info:
redirect: ngine_io.vultr.vultr_user_info
webfaction_app:
redirect: community.general.webfaction_app
webfaction_db:
redirect: community.general.webfaction_db
webfaction_domain:
redirect: community.general.webfaction_domain
webfaction_mailbox:
redirect: community.general.webfaction_mailbox
webfaction_site:
redirect: community.general.webfaction_site
xenserver_guest_facts:
redirect: community.general.xenserver_guest_facts
xenserver_guest:
redirect: community.general.xenserver_guest
xenserver_guest_info:
redirect: community.general.xenserver_guest_info
xenserver_guest_powerstate:
redirect: community.general.xenserver_guest_powerstate
consul:
redirect: community.general.consul
consul_acl:
redirect: community.general.consul_acl
consul_kv:
redirect: community.general.consul_kv
consul_session:
redirect: community.general.consul_session
etcd3:
redirect: community.general.etcd3
pacemaker_cluster:
redirect: community.general.pacemaker_cluster
znode:
redirect: community.general.znode
aerospike_migrations:
redirect: community.general.aerospike_migrations
influxdb_database:
redirect: community.general.influxdb_database
influxdb_query:
redirect: community.general.influxdb_query
influxdb_retention_policy:
redirect: community.general.influxdb_retention_policy
influxdb_user:
redirect: community.general.influxdb_user
influxdb_write:
redirect: community.general.influxdb_write
elasticsearch_plugin:
redirect: community.general.elasticsearch_plugin
kibana_plugin:
redirect: community.general.kibana_plugin
redis:
redirect: community.general.redis
riak:
redirect: community.general.riak
mssql_db:
redirect: community.general.mssql_db
mysql_db:
redirect: community.mysql.mysql_db
mysql_info:
redirect: community.mysql.mysql_info
mysql_query:
redirect: community.mysql.mysql_query
mysql_replication:
redirect: community.mysql.mysql_replication
mysql_user:
redirect: community.mysql.mysql_user
mysql_variables:
redirect: community.mysql.mysql_variables
postgresql_copy:
redirect: community.postgresql.postgresql_copy
postgresql_db:
redirect: community.postgresql.postgresql_db
postgresql_ext:
redirect: community.postgresql.postgresql_ext
postgresql_idx:
redirect: community.postgresql.postgresql_idx
postgresql_info:
redirect: community.postgresql.postgresql_info
postgresql_lang:
redirect: community.postgresql.postgresql_lang
postgresql_membership:
redirect: community.postgresql.postgresql_membership
postgresql_owner:
redirect: community.postgresql.postgresql_owner
postgresql_pg_hba:
redirect: community.postgresql.postgresql_pg_hba
postgresql_ping:
redirect: community.postgresql.postgresql_ping
postgresql_privs:
redirect: community.postgresql.postgresql_privs
postgresql_publication:
redirect: community.postgresql.postgresql_publication
postgresql_query:
redirect: community.postgresql.postgresql_query
postgresql_schema:
redirect: community.postgresql.postgresql_schema
postgresql_sequence:
redirect: community.postgresql.postgresql_sequence
postgresql_set:
redirect: community.postgresql.postgresql_set
postgresql_slot:
redirect: community.postgresql.postgresql_slot
postgresql_subscription:
redirect: community.postgresql.postgresql_subscription
postgresql_table:
redirect: community.postgresql.postgresql_table
postgresql_tablespace:
redirect: community.postgresql.postgresql_tablespace
postgresql_user:
redirect: community.postgresql.postgresql_user
postgresql_user_obj_stat_info:
redirect: community.postgresql.postgresql_user_obj_stat_info
proxysql_backend_servers:
redirect: community.proxysql.proxysql_backend_servers
proxysql_global_variables:
redirect: community.proxysql.proxysql_global_variables
proxysql_manage_config:
redirect: community.proxysql.proxysql_manage_config
proxysql_mysql_users:
redirect: community.proxysql.proxysql_mysql_users
proxysql_query_rules:
redirect: community.proxysql.proxysql_query_rules
proxysql_replication_hostgroups:
redirect: community.proxysql.proxysql_replication_hostgroups
proxysql_scheduler:
redirect: community.proxysql.proxysql_scheduler
vertica_facts:
redirect: community.general.vertica_facts
vertica_configuration:
redirect: community.general.vertica_configuration
vertica_info:
redirect: community.general.vertica_info
vertica_role:
redirect: community.general.vertica_role
vertica_schema:
redirect: community.general.vertica_schema
vertica_user:
redirect: community.general.vertica_user
archive:
redirect: community.general.archive
ini_file:
redirect: community.general.ini_file
iso_extract:
redirect: community.general.iso_extract
patch:
redirect: ansible.posix.patch
read_csv:
redirect: community.general.read_csv
xattr:
redirect: community.general.xattr
xml:
redirect: community.general.xml
onepassword_facts:
redirect: community.general.onepassword_facts
ipa_config:
redirect: community.general.ipa_config
ipa_dnsrecord:
redirect: community.general.ipa_dnsrecord
ipa_dnszone:
redirect: community.general.ipa_dnszone
ipa_group:
redirect: community.general.ipa_group
ipa_hbacrule:
redirect: community.general.ipa_hbacrule
ipa_host:
redirect: community.general.ipa_host
ipa_hostgroup:
redirect: community.general.ipa_hostgroup
ipa_role:
redirect: community.general.ipa_role
ipa_service:
redirect: community.general.ipa_service
ipa_subca:
redirect: community.general.ipa_subca
ipa_sudocmd:
redirect: community.general.ipa_sudocmd
ipa_sudocmdgroup:
redirect: community.general.ipa_sudocmdgroup
ipa_sudorule:
redirect: community.general.ipa_sudorule
ipa_user:
redirect: community.general.ipa_user
ipa_vault:
redirect: community.general.ipa_vault
keycloak_client:
redirect: community.general.keycloak_client
keycloak_clienttemplate:
redirect: community.general.keycloak_clienttemplate
keycloak_group:
redirect: community.general.keycloak_group
onepassword_info:
redirect: community.general.onepassword_info
opendj_backendprop:
redirect: community.general.opendj_backendprop
rabbitmq_binding:
redirect: community.rabbitmq.rabbitmq_binding
rabbitmq_exchange:
redirect: community.rabbitmq.rabbitmq_exchange
rabbitmq_global_parameter:
redirect: community.rabbitmq.rabbitmq_global_parameter
rabbitmq_parameter:
redirect: community.rabbitmq.rabbitmq_parameter
rabbitmq_plugin:
redirect: community.rabbitmq.rabbitmq_plugin
rabbitmq_policy:
redirect: community.rabbitmq.rabbitmq_policy
rabbitmq_queue:
redirect: community.rabbitmq.rabbitmq_queue
rabbitmq_user:
redirect: community.rabbitmq.rabbitmq_user
rabbitmq_vhost:
redirect: community.rabbitmq.rabbitmq_vhost
rabbitmq_vhost_limits:
redirect: community.rabbitmq.rabbitmq_vhost_limits
airbrake_deployment:
redirect: community.general.airbrake_deployment
bigpanda:
redirect: community.general.bigpanda
circonus_annotation:
redirect: community.general.circonus_annotation
datadog_event:
redirect: community.general.datadog_event
datadog_monitor:
redirect: community.general.datadog_monitor
honeybadger_deployment:
redirect: community.general.honeybadger_deployment
icinga2_feature:
redirect: community.general.icinga2_feature
icinga2_host:
redirect: community.general.icinga2_host
librato_annotation:
redirect: community.general.librato_annotation
logentries:
redirect: community.general.logentries
logicmonitor:
redirect: community.general.logicmonitor
logicmonitor_facts:
redirect: community.general.logicmonitor_facts
logstash_plugin:
redirect: community.general.logstash_plugin
monit:
redirect: community.general.monit
nagios:
redirect: community.general.nagios
newrelic_deployment:
redirect: community.general.newrelic_deployment
pagerduty:
redirect: community.general.pagerduty
pagerduty_alert:
redirect: community.general.pagerduty_alert
pingdom:
redirect: community.general.pingdom
rollbar_deployment:
redirect: community.general.rollbar_deployment
sensu_check:
redirect: community.general.sensu_check
sensu_client:
redirect: community.general.sensu_client
sensu_handler:
redirect: community.general.sensu_handler
sensu_silence:
redirect: community.general.sensu_silence
sensu_subscription:
redirect: community.general.sensu_subscription
spectrum_device:
redirect: community.general.spectrum_device
stackdriver:
redirect: community.general.stackdriver
statusio_maintenance:
redirect: community.general.statusio_maintenance
uptimerobot:
redirect: community.general.uptimerobot
zabbix_group_facts:
redirect: community.zabbix.zabbix_group_facts
zabbix_host_facts:
redirect: community.zabbix.zabbix_host_facts
zabbix_action:
redirect: community.zabbix.zabbix_action
zabbix_group:
redirect: community.zabbix.zabbix_group
zabbix_group_info:
redirect: community.zabbix.zabbix_group_info
zabbix_host:
redirect: community.zabbix.zabbix_host
zabbix_host_events_info:
redirect: community.zabbix.zabbix_host_events_info
zabbix_host_info:
redirect: community.zabbix.zabbix_host_info
zabbix_hostmacro:
redirect: community.zabbix.zabbix_hostmacro
zabbix_maintenance:
redirect: community.zabbix.zabbix_maintenance
zabbix_map:
redirect: community.zabbix.zabbix_map
zabbix_mediatype:
redirect: community.zabbix.zabbix_mediatype
zabbix_proxy:
redirect: community.zabbix.zabbix_proxy
zabbix_screen:
redirect: community.zabbix.zabbix_screen
zabbix_service:
redirect: community.zabbix.zabbix_service
zabbix_template:
redirect: community.zabbix.zabbix_template
zabbix_template_info:
redirect: community.zabbix.zabbix_template_info
zabbix_user:
redirect: community.zabbix.zabbix_user
zabbix_user_info:
redirect: community.zabbix.zabbix_user_info
zabbix_valuemap:
redirect: community.zabbix.zabbix_valuemap
cloudflare_dns:
redirect: community.general.cloudflare_dns
dnsimple:
redirect: community.general.dnsimple
dnsmadeeasy:
redirect: community.general.dnsmadeeasy
exo_dns_domain:
redirect: ngine_io.exoscale.exo_dns_domain
exo_dns_record:
redirect: ngine_io.exoscale.exo_dns_record
haproxy:
redirect: community.general.haproxy
hetzner_failover_ip:
redirect: community.hrobot.failover_ip
hetzner_failover_ip_info:
redirect: community.hrobot.failover_ip_info
hetzner_firewall:
redirect: community.hrobot.firewall
hetzner_firewall_info:
redirect: community.hrobot.firewall_info
infinity:
redirect: community.general.infinity
ip_netns:
redirect: community.general.ip_netns
ipify_facts:
redirect: community.general.ipify_facts
ipinfoio_facts:
redirect: community.general.ipinfoio_facts
ipwcli_dns:
redirect: community.general.ipwcli_dns
ldap_attr:
redirect: community.general.ldap_attr
ldap_attrs:
redirect: community.general.ldap_attrs
ldap_entry:
redirect: community.general.ldap_entry
ldap_passwd:
redirect: community.general.ldap_passwd
lldp:
redirect: community.general.lldp
netcup_dns:
redirect: community.general.netcup_dns
nios_a_record:
redirect: community.general.nios_a_record
nios_aaaa_record:
redirect: community.general.nios_aaaa_record
nios_cname_record:
redirect: community.general.nios_cname_record
nios_dns_view:
redirect: community.general.nios_dns_view
nios_fixed_address:
redirect: community.general.nios_fixed_address
nios_host_record:
redirect: community.general.nios_host_record
nios_member:
redirect: community.general.nios_member
nios_mx_record:
redirect: community.general.nios_mx_record
nios_naptr_record:
redirect: community.general.nios_naptr_record
nios_network:
redirect: community.general.nios_network
nios_network_view:
redirect: community.general.nios_network_view
nios_nsgroup:
redirect: community.general.nios_nsgroup
nios_ptr_record:
redirect: community.general.nios_ptr_record
nios_srv_record:
redirect: community.general.nios_srv_record
nios_txt_record:
redirect: community.general.nios_txt_record
nios_zone:
redirect: community.general.nios_zone
nmcli:
redirect: community.general.nmcli
nsupdate:
redirect: community.general.nsupdate
omapi_host:
redirect: community.general.omapi_host
snmp_facts:
redirect: community.general.snmp_facts
a10_server:
redirect: community.network.a10_server
a10_server_axapi3:
redirect: community.network.a10_server_axapi3
a10_service_group:
redirect: community.network.a10_service_group
a10_virtual_server:
redirect: community.network.a10_virtual_server
aci_intf_policy_fc:
redirect: cisco.aci.aci_interface_policy_fc
aci_intf_policy_l2:
redirect: cisco.aci.aci_interface_policy_l2
aci_intf_policy_lldp:
redirect: cisco.aci.aci_interface_policy_lldp
aci_intf_policy_mcp:
redirect: cisco.aci.aci_interface_policy_mcp
aci_intf_policy_port_channel:
redirect: cisco.aci.aci_interface_policy_port_channel
aci_intf_policy_port_security:
redirect: cisco.aci.aci_interface_policy_port_security
mso_schema_template_external_epg_contract:
redirect: cisco.mso.mso_schema_template_external_epg_contract
mso_schema_template_external_epg_subnet:
redirect: cisco.mso.mso_schema_template_external_epg_subnet
aireos_command:
redirect: community.network.aireos_command
aireos_config:
redirect: community.network.aireos_config
apconos_command:
redirect: community.network.apconos_command
aruba_command:
redirect: community.network.aruba_command
aruba_config:
redirect: community.network.aruba_config
avi_actiongroupconfig:
redirect: community.network.avi_actiongroupconfig
avi_alertconfig:
redirect: community.network.avi_alertconfig
avi_alertemailconfig:
redirect: community.network.avi_alertemailconfig
avi_alertscriptconfig:
redirect: community.network.avi_alertscriptconfig
avi_alertsyslogconfig:
redirect: community.network.avi_alertsyslogconfig
avi_analyticsprofile:
redirect: community.network.avi_analyticsprofile
avi_api_session:
redirect: community.network.avi_api_session
avi_api_version:
redirect: community.network.avi_api_version
avi_applicationpersistenceprofile:
redirect: community.network.avi_applicationpersistenceprofile
avi_applicationprofile:
redirect: community.network.avi_applicationprofile
avi_authprofile:
redirect: community.network.avi_authprofile
avi_autoscalelaunchconfig:
redirect: community.network.avi_autoscalelaunchconfig
avi_backup:
redirect: community.network.avi_backup
avi_backupconfiguration:
redirect: community.network.avi_backupconfiguration
avi_certificatemanagementprofile:
redirect: community.network.avi_certificatemanagementprofile
avi_cloud:
redirect: community.network.avi_cloud
avi_cloudconnectoruser:
redirect: community.network.avi_cloudconnectoruser
avi_cloudproperties:
redirect: community.network.avi_cloudproperties
avi_cluster:
redirect: community.network.avi_cluster
avi_clusterclouddetails:
redirect: community.network.avi_clusterclouddetails
avi_controllerproperties:
redirect: community.network.avi_controllerproperties
avi_customipamdnsprofile:
redirect: community.network.avi_customipamdnsprofile
avi_dnspolicy:
redirect: community.network.avi_dnspolicy
avi_errorpagebody:
redirect: community.network.avi_errorpagebody
avi_errorpageprofile:
redirect: community.network.avi_errorpageprofile
avi_gslb:
redirect: community.network.avi_gslb
avi_gslbgeodbprofile:
redirect: community.network.avi_gslbgeodbprofile
avi_gslbservice:
redirect: community.network.avi_gslbservice
avi_gslbservice_patch_member:
redirect: community.network.avi_gslbservice_patch_member
avi_hardwaresecuritymodulegroup:
redirect: community.network.avi_hardwaresecuritymodulegroup
avi_healthmonitor:
redirect: community.network.avi_healthmonitor
avi_httppolicyset:
redirect: community.network.avi_httppolicyset
avi_ipaddrgroup:
redirect: community.network.avi_ipaddrgroup
avi_ipamdnsproviderprofile:
redirect: community.network.avi_ipamdnsproviderprofile
avi_l4policyset:
redirect: community.network.avi_l4policyset
avi_microservicegroup:
redirect: community.network.avi_microservicegroup
avi_network:
redirect: community.network.avi_network
avi_networkprofile:
redirect: community.network.avi_networkprofile
avi_networksecuritypolicy:
redirect: community.network.avi_networksecuritypolicy
avi_pkiprofile:
redirect: community.network.avi_pkiprofile
avi_pool:
redirect: community.network.avi_pool
avi_poolgroup:
redirect: community.network.avi_poolgroup
avi_poolgroupdeploymentpolicy:
redirect: community.network.avi_poolgroupdeploymentpolicy
avi_prioritylabels:
redirect: community.network.avi_prioritylabels
avi_role:
redirect: community.network.avi_role
avi_scheduler:
redirect: community.network.avi_scheduler
avi_seproperties:
redirect: community.network.avi_seproperties
avi_serverautoscalepolicy:
redirect: community.network.avi_serverautoscalepolicy
avi_serviceengine:
redirect: community.network.avi_serviceengine
avi_serviceenginegroup:
redirect: community.network.avi_serviceenginegroup
avi_snmptrapprofile:
redirect: community.network.avi_snmptrapprofile
avi_sslkeyandcertificate:
redirect: community.network.avi_sslkeyandcertificate
avi_sslprofile:
redirect: community.network.avi_sslprofile
avi_stringgroup:
redirect: community.network.avi_stringgroup
avi_systemconfiguration:
redirect: community.network.avi_systemconfiguration
avi_tenant:
redirect: community.network.avi_tenant
avi_trafficcloneprofile:
redirect: community.network.avi_trafficcloneprofile
avi_user:
redirect: community.network.avi_user
avi_useraccount:
redirect: community.network.avi_useraccount
avi_useraccountprofile:
redirect: community.network.avi_useraccountprofile
avi_virtualservice:
redirect: community.network.avi_virtualservice
avi_vrfcontext:
redirect: community.network.avi_vrfcontext
avi_vsdatascriptset:
redirect: community.network.avi_vsdatascriptset
avi_vsvip:
redirect: community.network.avi_vsvip
avi_webhook:
redirect: community.network.avi_webhook
bcf_switch:
redirect: community.network.bcf_switch
bigmon_chain:
redirect: community.network.bigmon_chain
bigmon_policy:
redirect: community.network.bigmon_policy
checkpoint_access_layer_facts:
redirect: check_point.mgmt.checkpoint_access_layer_facts
checkpoint_access_rule:
redirect: check_point.mgmt.checkpoint_access_rule
checkpoint_access_rule_facts:
redirect: check_point.mgmt.checkpoint_access_rule_facts
checkpoint_host:
redirect: check_point.mgmt.checkpoint_host
checkpoint_host_facts:
redirect: check_point.mgmt.checkpoint_host_facts
checkpoint_object_facts:
redirect: check_point.mgmt.checkpoint_object_facts
checkpoint_run_script:
redirect: check_point.mgmt.checkpoint_run_script
checkpoint_session:
redirect: check_point.mgmt.checkpoint_session
checkpoint_task_facts:
redirect: check_point.mgmt.checkpoint_task_facts
cp_publish:
redirect: community.network.cp_publish
ce_aaa_server:
redirect: community.network.ce_aaa_server
ce_aaa_server_host:
redirect: community.network.ce_aaa_server_host
ce_acl:
redirect: community.network.ce_acl
ce_acl_advance:
redirect: community.network.ce_acl_advance
ce_acl_interface:
redirect: community.network.ce_acl_interface
ce_bfd_global:
redirect: community.network.ce_bfd_global
ce_bfd_session:
redirect: community.network.ce_bfd_session
ce_bfd_view:
redirect: community.network.ce_bfd_view
ce_bgp:
redirect: community.network.ce_bgp
ce_bgp_af:
redirect: community.network.ce_bgp_af
ce_bgp_neighbor:
redirect: community.network.ce_bgp_neighbor
ce_bgp_neighbor_af:
redirect: community.network.ce_bgp_neighbor_af
ce_command:
redirect: community.network.ce_command
ce_config:
redirect: community.network.ce_config
ce_dldp:
redirect: community.network.ce_dldp
ce_dldp_interface:
redirect: community.network.ce_dldp_interface
ce_eth_trunk:
redirect: community.network.ce_eth_trunk
ce_evpn_bd_vni:
redirect: community.network.ce_evpn_bd_vni
ce_evpn_bgp:
redirect: community.network.ce_evpn_bgp
ce_evpn_bgp_rr:
redirect: community.network.ce_evpn_bgp_rr
ce_evpn_global:
redirect: community.network.ce_evpn_global
ce_facts:
redirect: community.network.ce_facts
ce_file_copy:
redirect: community.network.ce_file_copy
ce_info_center_debug:
redirect: community.network.ce_info_center_debug
ce_info_center_global:
redirect: community.network.ce_info_center_global
ce_info_center_log:
redirect: community.network.ce_info_center_log
ce_info_center_trap:
redirect: community.network.ce_info_center_trap
ce_interface:
redirect: community.network.ce_interface
ce_interface_ospf:
redirect: community.network.ce_interface_ospf
ce_ip_interface:
redirect: community.network.ce_ip_interface
ce_is_is_instance:
redirect: community.network.ce_is_is_instance
ce_is_is_interface:
redirect: community.network.ce_is_is_interface
ce_is_is_view:
redirect: community.network.ce_is_is_view
ce_lacp:
redirect: community.network.ce_lacp
ce_link_status:
redirect: community.network.ce_link_status
ce_lldp:
redirect: community.network.ce_lldp
ce_lldp_interface:
redirect: community.network.ce_lldp_interface
ce_mdn_interface:
redirect: community.network.ce_mdn_interface
ce_mlag_config:
redirect: community.network.ce_mlag_config
ce_mlag_interface:
redirect: community.network.ce_mlag_interface
ce_mtu:
redirect: community.network.ce_mtu
ce_multicast_global:
redirect: community.network.ce_multicast_global
ce_multicast_igmp_enable:
redirect: community.network.ce_multicast_igmp_enable
ce_netconf:
redirect: community.network.ce_netconf
ce_netstream_aging:
redirect: community.network.ce_netstream_aging
ce_netstream_export:
redirect: community.network.ce_netstream_export
ce_netstream_global:
redirect: community.network.ce_netstream_global
ce_netstream_template:
redirect: community.network.ce_netstream_template
ce_ntp:
redirect: community.network.ce_ntp
ce_ntp_auth:
redirect: community.network.ce_ntp_auth
ce_ospf:
redirect: community.network.ce_ospf
ce_ospf_vrf:
redirect: community.network.ce_ospf_vrf
ce_reboot:
redirect: community.network.ce_reboot
ce_rollback:
redirect: community.network.ce_rollback
ce_sflow:
redirect: community.network.ce_sflow
ce_snmp_community:
redirect: community.network.ce_snmp_community
ce_snmp_contact:
redirect: community.network.ce_snmp_contact
ce_snmp_location:
redirect: community.network.ce_snmp_location
ce_snmp_target_host:
redirect: community.network.ce_snmp_target_host
ce_snmp_traps:
redirect: community.network.ce_snmp_traps
ce_snmp_user:
redirect: community.network.ce_snmp_user
ce_startup:
redirect: community.network.ce_startup
ce_static_route:
redirect: community.network.ce_static_route
ce_static_route_bfd:
redirect: community.network.ce_static_route_bfd
ce_stp:
redirect: community.network.ce_stp
ce_switchport:
redirect: community.network.ce_switchport
ce_vlan:
redirect: community.network.ce_vlan
ce_vrf:
redirect: community.network.ce_vrf
ce_vrf_af:
redirect: community.network.ce_vrf_af
ce_vrf_interface:
redirect: community.network.ce_vrf_interface
ce_vrrp:
redirect: community.network.ce_vrrp
ce_vxlan_arp:
redirect: community.network.ce_vxlan_arp
ce_vxlan_gateway:
redirect: community.network.ce_vxlan_gateway
ce_vxlan_global:
redirect: community.network.ce_vxlan_global
ce_vxlan_tunnel:
redirect: community.network.ce_vxlan_tunnel
ce_vxlan_vap:
redirect: community.network.ce_vxlan_vap
cv_server_provision:
redirect: community.network.cv_server_provision
cnos_backup:
redirect: community.network.cnos_backup
cnos_banner:
redirect: community.network.cnos_banner
cnos_bgp:
redirect: community.network.cnos_bgp
cnos_command:
redirect: community.network.cnos_command
cnos_conditional_command:
redirect: community.network.cnos_conditional_command
cnos_conditional_template:
redirect: community.network.cnos_conditional_template
cnos_config:
redirect: community.network.cnos_config
cnos_factory:
redirect: community.network.cnos_factory
cnos_facts:
redirect: community.network.cnos_facts
cnos_image:
redirect: community.network.cnos_image
cnos_interface:
redirect: community.network.cnos_interface
cnos_l2_interface:
redirect: community.network.cnos_l2_interface
cnos_l3_interface:
redirect: community.network.cnos_l3_interface
cnos_linkagg:
redirect: community.network.cnos_linkagg
cnos_lldp:
redirect: community.network.cnos_lldp
cnos_logging:
redirect: community.network.cnos_logging
cnos_reload:
redirect: community.network.cnos_reload
cnos_rollback:
redirect: community.network.cnos_rollback
cnos_save:
redirect: community.network.cnos_save
cnos_showrun:
redirect: community.network.cnos_showrun
cnos_static_route:
redirect: community.network.cnos_static_route
cnos_system:
redirect: community.network.cnos_system
cnos_template:
redirect: community.network.cnos_template
cnos_user:
redirect: community.network.cnos_user
cnos_vlag:
redirect: community.network.cnos_vlag
cnos_vlan:
redirect: community.network.cnos_vlan
cnos_vrf:
redirect: community.network.cnos_vrf
nclu:
redirect: community.network.nclu
edgeos_command:
redirect: community.network.edgeos_command
edgeos_config:
redirect: community.network.edgeos_config
edgeos_facts:
redirect: community.network.edgeos_facts
edgeswitch_facts:
redirect: community.network.edgeswitch_facts
edgeswitch_vlan:
redirect: community.network.edgeswitch_vlan
enos_command:
redirect: community.network.enos_command
enos_config:
redirect: community.network.enos_config
enos_facts:
redirect: community.network.enos_facts
eric_eccli_command:
redirect: community.network.eric_eccli_command
exos_command:
redirect: community.network.exos_command
exos_config:
redirect: community.network.exos_config
exos_facts:
redirect: community.network.exos_facts
exos_l2_interfaces:
redirect: community.network.exos_l2_interfaces
exos_lldp_global:
redirect: community.network.exos_lldp_global
exos_lldp_interfaces:
redirect: community.network.exos_lldp_interfaces
exos_vlans:
redirect: community.network.exos_vlans
bigip_asm_policy:
tombstone:
removal_date: "2019-11-06"
warning_text: bigip_asm_policy has been removed please use bigip_asm_policy_manage instead.
bigip_device_facts:
redirect: f5networks.f5_modules.bigip_device_info
bigip_iapplx_package:
redirect: f5networks.f5_modules.bigip_lx_package
bigip_security_address_list:
redirect: f5networks.f5_modules.bigip_firewall_address_list
bigip_security_port_list:
redirect: f5networks.f5_modules.bigip_firewall_port_list
bigip_traffic_group:
redirect: f5networks.f5_modules.bigip_device_traffic_group
bigip_facts:
tombstone:
removal_date: "2019-11-06"
warning_text: bigip_facts has been removed please use bigip_device_info module.
bigip_gtm_facts:
tombstone:
removal_date: "2019-11-06"
warning_text: bigip_gtm_facts has been removed please use bigip_device_info module.
faz_device:
redirect: community.fortios.faz_device
fmgr_device:
redirect: community.fortios.fmgr_device
fmgr_device_config:
redirect: community.fortios.fmgr_device_config
fmgr_device_group:
redirect: community.fortios.fmgr_device_group
fmgr_device_provision_template:
redirect: community.fortios.fmgr_device_provision_template
fmgr_fwobj_address:
redirect: community.fortios.fmgr_fwobj_address
fmgr_fwobj_ippool:
redirect: community.fortios.fmgr_fwobj_ippool
fmgr_fwobj_ippool6:
redirect: community.fortios.fmgr_fwobj_ippool6
fmgr_fwobj_service:
redirect: community.fortios.fmgr_fwobj_service
fmgr_fwobj_vip:
redirect: community.fortios.fmgr_fwobj_vip
fmgr_fwpol_ipv4:
redirect: community.fortios.fmgr_fwpol_ipv4
fmgr_fwpol_package:
redirect: community.fortios.fmgr_fwpol_package
fmgr_ha:
redirect: community.fortios.fmgr_ha
fmgr_provisioning:
redirect: community.fortios.fmgr_provisioning
fmgr_query:
redirect: community.fortios.fmgr_query
fmgr_script:
redirect: community.fortios.fmgr_script
fmgr_secprof_appctrl:
redirect: community.fortios.fmgr_secprof_appctrl
fmgr_secprof_av:
redirect: community.fortios.fmgr_secprof_av
fmgr_secprof_dns:
redirect: community.fortios.fmgr_secprof_dns
fmgr_secprof_ips:
redirect: community.fortios.fmgr_secprof_ips
fmgr_secprof_profile_group:
redirect: community.fortios.fmgr_secprof_profile_group
fmgr_secprof_proxy:
redirect: community.fortios.fmgr_secprof_proxy
fmgr_secprof_spam:
redirect: community.fortios.fmgr_secprof_spam
fmgr_secprof_ssl_ssh:
redirect: community.fortios.fmgr_secprof_ssl_ssh
fmgr_secprof_voip:
redirect: community.fortios.fmgr_secprof_voip
fmgr_secprof_waf:
redirect: community.fortios.fmgr_secprof_waf
fmgr_secprof_wanopt:
redirect: community.fortios.fmgr_secprof_wanopt
fmgr_secprof_web:
redirect: community.fortios.fmgr_secprof_web
ftd_configuration:
redirect: community.network.ftd_configuration
ftd_file_download:
redirect: community.network.ftd_file_download
ftd_file_upload:
redirect: community.network.ftd_file_upload
ftd_install:
redirect: community.network.ftd_install
icx_banner:
redirect: community.network.icx_banner
icx_command:
redirect: community.network.icx_command
icx_config:
redirect: community.network.icx_config
icx_copy:
redirect: community.network.icx_copy
icx_facts:
redirect: community.network.icx_facts
icx_interface:
redirect: community.network.icx_interface
icx_l3_interface:
redirect: community.network.icx_l3_interface
icx_linkagg:
redirect: community.network.icx_linkagg
icx_lldp:
redirect: community.network.icx_lldp
icx_logging:
redirect: community.network.icx_logging
icx_ping:
redirect: community.network.icx_ping
icx_static_route:
redirect: community.network.icx_static_route
icx_system:
redirect: community.network.icx_system
icx_user:
redirect: community.network.icx_user
icx_vlan:
redirect: community.network.icx_vlan
dladm_etherstub:
redirect: community.network.dladm_etherstub
dladm_iptun:
redirect: community.network.dladm_iptun
dladm_linkprop:
redirect: community.network.dladm_linkprop
dladm_vlan:
redirect: community.network.dladm_vlan
dladm_vnic:
redirect: community.network.dladm_vnic
flowadm:
redirect: community.network.flowadm
ipadm_addr:
redirect: community.network.ipadm_addr
ipadm_addrprop:
redirect: community.network.ipadm_addrprop
ipadm_if:
redirect: community.network.ipadm_if
ipadm_ifprop:
redirect: community.network.ipadm_ifprop
ipadm_prop:
redirect: community.network.ipadm_prop
ig_config:
redirect: community.network.ig_config
ig_unit_information:
redirect: community.network.ig_unit_information
ironware_command:
redirect: community.network.ironware_command
ironware_config:
redirect: community.network.ironware_config
ironware_facts:
redirect: community.network.ironware_facts
iap_start_workflow:
redirect: community.network.iap_start_workflow
iap_token:
redirect: community.network.iap_token
netact_cm_command:
redirect: community.network.netact_cm_command
netscaler_cs_action:
redirect: community.network.netscaler_cs_action
netscaler_cs_policy:
redirect: community.network.netscaler_cs_policy
netscaler_cs_vserver:
redirect: community.network.netscaler_cs_vserver
netscaler_gslb_service:
redirect: community.network.netscaler_gslb_service
netscaler_gslb_site:
redirect: community.network.netscaler_gslb_site
netscaler_gslb_vserver:
redirect: community.network.netscaler_gslb_vserver
netscaler_lb_monitor:
redirect: community.network.netscaler_lb_monitor
netscaler_lb_vserver:
redirect: community.network.netscaler_lb_vserver
netscaler_nitro_request:
redirect: community.network.netscaler_nitro_request
netscaler_save_config:
redirect: community.network.netscaler_save_config
netscaler_server:
redirect: community.network.netscaler_server
netscaler_service:
redirect: community.network.netscaler_service
netscaler_servicegroup:
redirect: community.network.netscaler_servicegroup
netscaler_ssl_certkey:
redirect: community.network.netscaler_ssl_certkey
pn_cluster:
redirect: community.network.pn_cluster
pn_ospf:
redirect: community.network.pn_ospf
pn_ospfarea:
redirect: community.network.pn_ospfarea
pn_show:
redirect: community.network.pn_show
pn_trunk:
redirect: community.network.pn_trunk
pn_vlag:
redirect: community.network.pn_vlag
pn_vlan:
redirect: community.network.pn_vlan
pn_vrouter:
redirect: community.network.pn_vrouter
pn_vrouterbgp:
redirect: community.network.pn_vrouterbgp
pn_vrouterif:
redirect: community.network.pn_vrouterif
pn_vrouterlbif:
redirect: community.network.pn_vrouterlbif
pn_access_list:
redirect: community.network.pn_access_list
pn_access_list_ip:
redirect: community.network.pn_access_list_ip
pn_admin_service:
redirect: community.network.pn_admin_service
pn_admin_session_timeout:
redirect: community.network.pn_admin_session_timeout
pn_admin_syslog:
redirect: community.network.pn_admin_syslog
pn_connection_stats_settings:
redirect: community.network.pn_connection_stats_settings
pn_cpu_class:
redirect: community.network.pn_cpu_class
pn_cpu_mgmt_class:
redirect: community.network.pn_cpu_mgmt_class
pn_dhcp_filter:
redirect: community.network.pn_dhcp_filter
pn_dscp_map:
redirect: community.network.pn_dscp_map
pn_dscp_map_pri_map:
redirect: community.network.pn_dscp_map_pri_map
pn_fabric_local:
redirect: community.network.pn_fabric_local
pn_igmp_snooping:
redirect: community.network.pn_igmp_snooping
pn_ipv6security_raguard:
redirect: community.network.pn_ipv6security_raguard
pn_ipv6security_raguard_port:
redirect: community.network.pn_ipv6security_raguard_port
pn_ipv6security_raguard_vlan:
redirect: community.network.pn_ipv6security_raguard_vlan
pn_log_audit_exception:
redirect: community.network.pn_log_audit_exception
pn_port_config:
redirect: community.network.pn_port_config
pn_port_cos_bw:
redirect: community.network.pn_port_cos_bw
pn_port_cos_rate_setting:
redirect: community.network.pn_port_cos_rate_setting
pn_prefix_list:
redirect: community.network.pn_prefix_list
pn_prefix_list_network:
redirect: community.network.pn_prefix_list_network
pn_role:
redirect: community.network.pn_role
pn_snmp_community:
redirect: community.network.pn_snmp_community
pn_snmp_trap_sink:
redirect: community.network.pn_snmp_trap_sink
pn_snmp_vacm:
redirect: community.network.pn_snmp_vacm
pn_stp:
redirect: community.network.pn_stp
pn_stp_port:
redirect: community.network.pn_stp_port
pn_switch_setup:
redirect: community.network.pn_switch_setup
pn_user:
redirect: community.network.pn_user
pn_vflow_table_profile:
redirect: community.network.pn_vflow_table_profile
pn_vrouter_bgp:
redirect: community.network.pn_vrouter_bgp
pn_vrouter_bgp_network:
redirect: community.network.pn_vrouter_bgp_network
pn_vrouter_interface_ip:
redirect: community.network.pn_vrouter_interface_ip
pn_vrouter_loopback_interface:
redirect: community.network.pn_vrouter_loopback_interface
pn_vrouter_ospf:
redirect: community.network.pn_vrouter_ospf
pn_vrouter_ospf6:
redirect: community.network.pn_vrouter_ospf6
pn_vrouter_packet_relay:
redirect: community.network.pn_vrouter_packet_relay
pn_vrouter_pim_config:
redirect: community.network.pn_vrouter_pim_config
pn_vtep:
redirect: community.network.pn_vtep
nos_command:
redirect: community.network.nos_command
nos_config:
redirect: community.network.nos_config
nos_facts:
redirect: community.network.nos_facts
nso_action:
redirect: cisco.nso.nso_action
nso_config:
redirect: cisco.nso.nso_config
nso_query:
redirect: cisco.nso.nso_query
nso_show:
redirect: cisco.nso.nso_show
nso_verify:
redirect: cisco.nso.nso_verify
nuage_vspk:
redirect: community.network.nuage_vspk
onyx_aaa:
redirect: mellanox.onyx.onyx_aaa
onyx_bfd:
redirect: mellanox.onyx.onyx_bfd
onyx_bgp:
redirect: mellanox.onyx.onyx_bgp
onyx_buffer_pool:
redirect: mellanox.onyx.onyx_buffer_pool
onyx_command:
redirect: mellanox.onyx.onyx_command
onyx_config:
redirect: mellanox.onyx.onyx_config
onyx_facts:
redirect: mellanox.onyx.onyx_facts
onyx_igmp:
redirect: mellanox.onyx.onyx_igmp
onyx_igmp_interface:
redirect: mellanox.onyx.onyx_igmp_interface
onyx_igmp_vlan:
redirect: mellanox.onyx.onyx_igmp_vlan
onyx_interface:
redirect: mellanox.onyx.onyx_interface
onyx_l2_interface:
redirect: mellanox.onyx.onyx_l2_interface
onyx_l3_interface:
redirect: mellanox.onyx.onyx_l3_interface
onyx_linkagg:
redirect: mellanox.onyx.onyx_linkagg
onyx_lldp:
redirect: mellanox.onyx.onyx_lldp
onyx_lldp_interface:
redirect: mellanox.onyx.onyx_lldp_interface
onyx_magp:
redirect: mellanox.onyx.onyx_magp
onyx_mlag_ipl:
redirect: mellanox.onyx.onyx_mlag_ipl
onyx_mlag_vip:
redirect: mellanox.onyx.onyx_mlag_vip
onyx_ntp:
redirect: mellanox.onyx.onyx_ntp
onyx_ntp_servers_peers:
redirect: mellanox.onyx.onyx_ntp_servers_peers
onyx_ospf:
redirect: mellanox.onyx.onyx_ospf
onyx_pfc_interface:
redirect: mellanox.onyx.onyx_pfc_interface
onyx_protocol:
redirect: mellanox.onyx.onyx_protocol
onyx_ptp_global:
redirect: mellanox.onyx.onyx_ptp_global
onyx_ptp_interface:
redirect: mellanox.onyx.onyx_ptp_interface
onyx_qos:
redirect: mellanox.onyx.onyx_qos
onyx_snmp:
redirect: mellanox.onyx.onyx_snmp
onyx_snmp_hosts:
redirect: mellanox.onyx.onyx_snmp_hosts
onyx_snmp_users:
redirect: mellanox.onyx.onyx_snmp_users
onyx_syslog_files:
redirect: mellanox.onyx.onyx_syslog_files
onyx_syslog_remote:
redirect: mellanox.onyx.onyx_syslog_remote
onyx_traffic_class:
redirect: mellanox.onyx.onyx_traffic_class
onyx_username:
redirect: mellanox.onyx.onyx_username
onyx_vlan:
redirect: mellanox.onyx.onyx_vlan
onyx_vxlan:
redirect: mellanox.onyx.onyx_vxlan
onyx_wjh:
redirect: mellanox.onyx.onyx_wjh
opx_cps:
redirect: community.network.opx_cps
ordnance_config:
redirect: community.network.ordnance_config
ordnance_facts:
redirect: community.network.ordnance_facts
panos_admin:
redirect: community.network.panos_admin
panos_admpwd:
redirect: community.network.panos_admpwd
panos_cert_gen_ssh:
redirect: community.network.panos_cert_gen_ssh
panos_check:
redirect: community.network.panos_check
panos_commit:
redirect: community.network.panos_commit
panos_dag:
redirect: community.network.panos_dag
panos_dag_tags:
redirect: community.network.panos_dag_tags
panos_import:
redirect: community.network.panos_import
panos_interface:
redirect: community.network.panos_interface
panos_lic:
redirect: community.network.panos_lic
panos_loadcfg:
redirect: community.network.panos_loadcfg
panos_match_rule:
redirect: community.network.panos_match_rule
panos_mgtconfig:
redirect: community.network.panos_mgtconfig
panos_nat_rule:
redirect: community.network.panos_nat_rule
panos_object:
redirect: community.network.panos_object
panos_op:
redirect: community.network.panos_op
panos_pg:
redirect: community.network.panos_pg
panos_query_rules:
redirect: community.network.panos_query_rules
panos_restart:
redirect: community.network.panos_restart
panos_sag:
redirect: community.network.panos_sag
panos_security_rule:
redirect: community.network.panos_security_rule
panos_set:
redirect: community.network.panos_set
vdirect_commit:
redirect: community.network.vdirect_commit
vdirect_file:
redirect: community.network.vdirect_file
vdirect_runnable:
redirect: community.network.vdirect_runnable
routeros_command:
redirect: community.routeros.command
routeros_facts:
redirect: community.routeros.facts
slxos_command:
redirect: community.network.slxos_command
slxos_config:
redirect: community.network.slxos_config
slxos_facts:
redirect: community.network.slxos_facts
slxos_interface:
redirect: community.network.slxos_interface
slxos_l2_interface:
redirect: community.network.slxos_l2_interface
slxos_l3_interface:
redirect: community.network.slxos_l3_interface
slxos_linkagg:
redirect: community.network.slxos_linkagg
slxos_lldp:
redirect: community.network.slxos_lldp
slxos_vlan:
redirect: community.network.slxos_vlan
sros_command:
redirect: community.network.sros_command
sros_config:
redirect: community.network.sros_config
sros_rollback:
redirect: community.network.sros_rollback
voss_command:
redirect: community.network.voss_command
voss_config:
redirect: community.network.voss_config
voss_facts:
redirect: community.network.voss_facts
osx_say:
redirect: community.general.say
bearychat:
redirect: community.general.bearychat
campfire:
redirect: community.general.campfire
catapult:
redirect: community.general.catapult
cisco_spark:
redirect: community.general.cisco_spark
flowdock:
redirect: community.general.flowdock
grove:
redirect: community.general.grove
hipchat:
redirect: community.general.hipchat
irc:
redirect: community.general.irc
jabber:
redirect: community.general.jabber
logentries_msg:
redirect: community.general.logentries_msg
mail:
redirect: community.general.mail
matrix:
redirect: community.general.matrix
mattermost:
redirect: community.general.mattermost
mqtt:
redirect: community.general.mqtt
nexmo:
redirect: community.general.nexmo
office_365_connector_card:
redirect: community.general.office_365_connector_card
pushbullet:
redirect: community.general.pushbullet
pushover:
redirect: community.general.pushover
rabbitmq_publish:
redirect: community.rabbitmq.rabbitmq_publish
rocketchat:
redirect: community.general.rocketchat
say:
redirect: community.general.say
sendgrid:
redirect: community.general.sendgrid
slack:
redirect: community.general.slack
syslogger:
redirect: community.general.syslogger
telegram:
redirect: community.general.telegram
twilio:
redirect: community.general.twilio
typetalk:
redirect: community.general.typetalk
bower:
redirect: community.general.bower
bundler:
redirect: community.general.bundler
composer:
redirect: community.general.composer
cpanm:
redirect: community.general.cpanm
easy_install:
redirect: community.general.easy_install
gem:
redirect: community.general.gem
maven_artifact:
redirect: community.general.maven_artifact
npm:
redirect: community.general.npm
pear:
redirect: community.general.pear
pip_package_info:
redirect: community.general.pip_package_info
yarn:
redirect: community.general.yarn
apk:
redirect: community.general.apk
apt_rpm:
redirect: community.general.apt_rpm
flatpak:
redirect: community.general.flatpak
flatpak_remote:
redirect: community.general.flatpak_remote
homebrew:
redirect: community.general.homebrew
homebrew_cask:
redirect: community.general.homebrew_cask
homebrew_tap:
redirect: community.general.homebrew_tap
installp:
redirect: community.general.installp
layman:
redirect: community.general.layman
macports:
redirect: community.general.macports
mas:
redirect: community.general.mas
openbsd_pkg:
redirect: community.general.openbsd_pkg
opkg:
redirect: community.general.opkg
pacman:
redirect: community.general.pacman
pkg5:
redirect: community.general.pkg5
pkg5_publisher:
redirect: community.general.pkg5_publisher
pkgin:
redirect: community.general.pkgin
pkgng:
redirect: community.general.pkgng
pkgutil:
redirect: community.general.pkgutil
portage:
redirect: community.general.portage
portinstall:
redirect: community.general.portinstall
pulp_repo:
redirect: community.general.pulp_repo
redhat_subscription:
redirect: community.general.redhat_subscription
rhn_channel:
redirect: community.general.rhn_channel
rhn_register:
redirect: community.general.rhn_register
rhsm_release:
redirect: community.general.rhsm_release
rhsm_repository:
redirect: community.general.rhsm_repository
slackpkg:
redirect: community.general.slackpkg
snap:
redirect: community.general.snap
sorcery:
redirect: community.general.sorcery
svr4pkg:
redirect: community.general.svr4pkg
swdepot:
redirect: community.general.swdepot
swupd:
redirect: community.general.swupd
urpmi:
redirect: community.general.urpmi
xbps:
redirect: community.general.xbps
zypper:
redirect: community.general.zypper
zypper_repository:
redirect: community.general.zypper_repository
cobbler_sync:
redirect: community.general.cobbler_sync
cobbler_system:
redirect: community.general.cobbler_system
idrac_firmware:
redirect: dellemc.openmanage.idrac_firmware
idrac_server_config_profile:
redirect: dellemc.openmanage.idrac_server_config_profile
ome_device_info:
redirect: dellemc.openmanage.ome_device_info
foreman:
redirect: community.general.foreman
katello:
redirect: community.general.katello
hpilo_facts:
redirect: community.general.hpilo_facts
hpilo_boot:
redirect: community.general.hpilo_boot
hpilo_info:
redirect: community.general.hpilo_info
hponcfg:
redirect: community.general.hponcfg
imc_rest:
redirect: community.general.imc_rest
ipmi_boot:
redirect: community.general.ipmi_boot
ipmi_power:
redirect: community.general.ipmi_power
lxca_cmms:
redirect: community.general.lxca_cmms
lxca_nodes:
redirect: community.general.lxca_nodes
manageiq_alert_profiles:
redirect: community.general.manageiq_alert_profiles
manageiq_alerts:
redirect: community.general.manageiq_alerts
manageiq_group:
redirect: community.general.manageiq_group
manageiq_policies:
redirect: community.general.manageiq_policies
manageiq_provider:
redirect: community.general.manageiq_provider
manageiq_tags:
redirect: community.general.manageiq_tags
manageiq_tenant:
redirect: community.general.manageiq_tenant
manageiq_user:
redirect: community.general.manageiq_user
oneview_datacenter_facts:
redirect: community.general.oneview_datacenter_facts
oneview_enclosure_facts:
redirect: community.general.oneview_enclosure_facts
oneview_ethernet_network_facts:
redirect: community.general.oneview_ethernet_network_facts
oneview_fc_network_facts:
redirect: community.general.oneview_fc_network_facts
oneview_fcoe_network_facts:
redirect: community.general.oneview_fcoe_network_facts
oneview_logical_interconnect_group_facts:
redirect: community.general.oneview_logical_interconnect_group_facts
oneview_network_set_facts:
redirect: community.general.oneview_network_set_facts
oneview_san_manager_facts:
redirect: community.general.oneview_san_manager_facts
oneview_datacenter_info:
redirect: community.general.oneview_datacenter_info
oneview_enclosure_info:
redirect: community.general.oneview_enclosure_info
oneview_ethernet_network:
redirect: community.general.oneview_ethernet_network
oneview_ethernet_network_info:
redirect: community.general.oneview_ethernet_network_info
oneview_fc_network:
redirect: community.general.oneview_fc_network
oneview_fc_network_info:
redirect: community.general.oneview_fc_network_info
oneview_fcoe_network:
redirect: community.general.oneview_fcoe_network
oneview_fcoe_network_info:
redirect: community.general.oneview_fcoe_network_info
oneview_logical_interconnect_group:
redirect: community.general.oneview_logical_interconnect_group
oneview_logical_interconnect_group_info:
redirect: community.general.oneview_logical_interconnect_group_info
oneview_network_set:
redirect: community.general.oneview_network_set
oneview_network_set_info:
redirect: community.general.oneview_network_set_info
oneview_san_manager:
redirect: community.general.oneview_san_manager
oneview_san_manager_info:
redirect: community.general.oneview_san_manager_info
idrac_redfish_facts:
redirect: community.general.idrac_redfish_facts
redfish_facts:
redirect: community.general.redfish_facts
idrac_redfish_command:
redirect: community.general.idrac_redfish_command
idrac_redfish_config:
redirect: community.general.idrac_redfish_config
idrac_redfish_info:
redirect: community.general.idrac_redfish_info
redfish_command:
redirect: community.general.redfish_command
redfish_config:
redirect: community.general.redfish_config
redfish_info:
redirect: community.general.redfish_info
stacki_host:
redirect: community.general.stacki_host
wakeonlan:
redirect: community.general.wakeonlan
bitbucket_access_key:
redirect: community.general.bitbucket_access_key
bitbucket_pipeline_key_pair:
redirect: community.general.bitbucket_pipeline_key_pair
bitbucket_pipeline_known_host:
redirect: community.general.bitbucket_pipeline_known_host
bitbucket_pipeline_variable:
redirect: community.general.bitbucket_pipeline_variable
bzr:
redirect: community.general.bzr
git_config:
redirect: community.general.git_config
github_hooks:
redirect: community.general.github_hooks
github_webhook_facts:
redirect: community.general.github_webhook_info
github_deploy_key:
redirect: community.general.github_deploy_key
github_issue:
redirect: community.general.github_issue
github_key:
redirect: community.general.github_key
github_release:
redirect: community.general.github_release
github_webhook:
redirect: community.general.github_webhook
github_webhook_info:
redirect: community.general.github_webhook_info
gitlab_hooks:
redirect: community.general.gitlab_hook
gitlab_deploy_key:
redirect: community.general.gitlab_deploy_key
gitlab_group:
redirect: community.general.gitlab_group
gitlab_hook:
redirect: community.general.gitlab_hook
gitlab_project:
redirect: community.general.gitlab_project
gitlab_project_variable:
redirect: community.general.gitlab_project_variable
gitlab_runner:
redirect: community.general.gitlab_runner
gitlab_user:
redirect: community.general.gitlab_user
hg:
redirect: community.general.hg
emc_vnx_sg_member:
redirect: community.general.emc_vnx_sg_member
gluster_heal_facts:
redirect: gluster.gluster.gluster_heal_info
gluster_heal_info:
redirect: gluster.gluster.gluster_heal_info
gluster_peer:
redirect: gluster.gluster.gluster_peer
gluster_volume:
redirect: gluster.gluster.gluster_volume
ss_3par_cpg:
redirect: community.general.ss_3par_cpg
ibm_sa_domain:
redirect: community.general.ibm_sa_domain
ibm_sa_host:
redirect: community.general.ibm_sa_host
ibm_sa_host_ports:
redirect: community.general.ibm_sa_host_ports
ibm_sa_pool:
redirect: community.general.ibm_sa_pool
ibm_sa_vol:
redirect: community.general.ibm_sa_vol
ibm_sa_vol_map:
redirect: community.general.ibm_sa_vol_map
infini_export:
redirect: infinidat.infinibox.infini_export
infini_export_client:
redirect: infinidat.infinibox.infini_export_client
infini_fs:
redirect: infinidat.infinibox.infini_fs
infini_host:
redirect: infinidat.infinibox.infini_host
infini_pool:
redirect: infinidat.infinibox.infini_pool
infini_vol:
redirect: infinidat.infinibox.infini_vol
na_cdot_aggregate:
redirect: community.general.na_cdot_aggregate
na_cdot_license:
redirect: community.general.na_cdot_license
na_cdot_lun:
redirect: community.general.na_cdot_lun
na_cdot_qtree:
redirect: community.general.na_cdot_qtree
na_cdot_svm:
redirect: community.general.na_cdot_svm
na_cdot_user:
redirect: community.general.na_cdot_user
na_cdot_user_role:
redirect: community.general.na_cdot_user_role
na_cdot_volume:
redirect: community.general.na_cdot_volume
na_ontap_gather_facts:
redirect: community.general.na_ontap_gather_facts
sf_account_manager:
redirect: community.general.sf_account_manager
sf_check_connections:
redirect: community.general.sf_check_connections
sf_snapshot_schedule_manager:
redirect: community.general.sf_snapshot_schedule_manager
sf_volume_access_group_manager:
redirect: community.general.sf_volume_access_group_manager
sf_volume_manager:
redirect: community.general.sf_volume_manager
netapp_e_alerts:
redirect: netapp_eseries.santricity.netapp_e_alerts
netapp_e_amg:
redirect: netapp_eseries.santricity.netapp_e_amg
netapp_e_amg_role:
redirect: netapp_eseries.santricity.netapp_e_amg_role
netapp_e_amg_sync:
redirect: netapp_eseries.santricity.netapp_e_amg_sync
netapp_e_asup:
redirect: netapp_eseries.santricity.netapp_e_asup
netapp_e_auditlog:
redirect: netapp_eseries.santricity.netapp_e_auditlog
netapp_e_auth:
redirect: netapp_eseries.santricity.netapp_e_auth
netapp_e_drive_firmware:
redirect: netapp_eseries.santricity.netapp_e_drive_firmware
netapp_e_facts:
redirect: netapp_eseries.santricity.netapp_e_facts
netapp_e_firmware:
redirect: netapp_eseries.santricity.netapp_e_firmware
netapp_e_flashcache:
redirect: netapp_eseries.santricity.netapp_e_flashcache
netapp_e_global:
redirect: netapp_eseries.santricity.netapp_e_global
netapp_e_host:
redirect: netapp_eseries.santricity.netapp_e_host
netapp_e_hostgroup:
redirect: netapp_eseries.santricity.netapp_e_hostgroup
netapp_e_iscsi_interface:
redirect: netapp_eseries.santricity.netapp_e_iscsi_interface
netapp_e_iscsi_target:
redirect: netapp_eseries.santricity.netapp_e_iscsi_target
netapp_e_ldap:
redirect: netapp_eseries.santricity.netapp_e_ldap
netapp_e_lun_mapping:
redirect: netapp_eseries.santricity.netapp_e_lun_mapping
netapp_e_mgmt_interface:
redirect: netapp_eseries.santricity.netapp_e_mgmt_interface
netapp_e_snapshot_group:
redirect: netapp_eseries.santricity.netapp_e_snapshot_group
netapp_e_snapshot_images:
redirect: netapp_eseries.santricity.netapp_e_snapshot_images
netapp_e_snapshot_volume:
redirect: netapp_eseries.santricity.netapp_e_snapshot_volume
netapp_e_storage_system:
redirect: netapp_eseries.santricity.netapp_e_storage_system
netapp_e_storagepool:
redirect: netapp_eseries.santricity.netapp_e_storagepool
netapp_e_syslog:
redirect: netapp_eseries.santricity.netapp_e_syslog
netapp_e_volume:
redirect: netapp_eseries.santricity.netapp_e_volume
netapp_e_volume_copy:
redirect: netapp_eseries.santricity.netapp_e_volume_copy
purefa_facts:
redirect: community.general.purefa_facts
purefb_facts:
redirect: community.general.purefb_facts
vexata_eg:
redirect: community.general.vexata_eg
vexata_volume:
redirect: community.general.vexata_volume
zfs:
redirect: community.general.zfs
zfs_delegate_admin:
redirect: community.general.zfs_delegate_admin
zfs_facts:
redirect: community.general.zfs_facts
zpool_facts:
redirect: community.general.zpool_facts
python_requirements_facts:
redirect: community.general.python_requirements_facts
aix_devices:
redirect: community.general.aix_devices
aix_filesystem:
redirect: community.general.aix_filesystem
aix_inittab:
redirect: community.general.aix_inittab
aix_lvg:
redirect: community.general.aix_lvg
aix_lvol:
redirect: community.general.aix_lvol
alternatives:
redirect: community.general.alternatives
awall:
redirect: community.general.awall
beadm:
redirect: community.general.beadm
capabilities:
redirect: community.general.capabilities
cronvar:
redirect: community.general.cronvar
crypttab:
redirect: community.general.crypttab
dconf:
redirect: community.general.dconf
facter:
redirect: community.general.facter
filesystem:
redirect: community.general.filesystem
firewalld:
redirect: ansible.posix.firewalld
gconftool2:
redirect: community.general.gconftool2
interfaces_file:
redirect: community.general.interfaces_file
java_cert:
redirect: community.general.java_cert
java_keystore:
redirect: community.general.java_keystore
kernel_blacklist:
redirect: community.general.kernel_blacklist
lbu:
redirect: community.general.lbu
listen_ports_facts:
redirect: community.general.listen_ports_facts
locale_gen:
redirect: community.general.locale_gen
lvg:
redirect: community.general.lvg
lvol:
redirect: community.general.lvol
make:
redirect: community.general.make
mksysb:
redirect: community.general.mksysb
modprobe:
redirect: community.general.modprobe
nosh:
redirect: community.general.nosh
ohai:
redirect: community.general.ohai
open_iscsi:
redirect: community.general.open_iscsi
openwrt_init:
redirect: community.general.openwrt_init
osx_defaults:
redirect: community.general.osx_defaults
pam_limits:
redirect: community.general.pam_limits
pamd:
redirect: community.general.pamd
parted:
redirect: community.general.parted
pids:
redirect: community.general.pids
puppet:
redirect: community.general.puppet
python_requirements_info:
redirect: community.general.python_requirements_info
runit:
redirect: community.general.runit
sefcontext:
redirect: community.general.sefcontext
selinux_permissive:
redirect: community.general.selinux_permissive
selogin:
redirect: community.general.selogin
seport:
redirect: community.general.seport
solaris_zone:
redirect: community.general.solaris_zone
svc:
redirect: community.general.svc
syspatch:
redirect: community.general.syspatch
timezone:
redirect: community.general.timezone
ufw:
redirect: community.general.ufw
vdo:
redirect: community.general.vdo
xfconf:
redirect: community.general.xfconf
xfs_quota:
redirect: community.general.xfs_quota
jenkins_job_facts:
redirect: community.general.jenkins_job_facts
nginx_status_facts:
redirect: community.general.nginx_status_facts
apache2_mod_proxy:
redirect: community.general.apache2_mod_proxy
apache2_module:
redirect: community.general.apache2_module
deploy_helper:
redirect: community.general.deploy_helper
django_manage:
redirect: community.general.django_manage
ejabberd_user:
redirect: community.general.ejabberd_user
gunicorn:
redirect: community.general.gunicorn
htpasswd:
redirect: community.general.htpasswd
jboss:
redirect: community.general.jboss
jenkins_job:
redirect: community.general.jenkins_job
jenkins_job_info:
redirect: community.general.jenkins_job_info
jenkins_plugin:
redirect: community.general.jenkins_plugin
jenkins_script:
redirect: community.general.jenkins_script
jira:
redirect: community.general.jira
nginx_status_info:
redirect: community.general.nginx_status_info
rundeck_acl_policy:
redirect: community.general.rundeck_acl_policy
rundeck_project:
redirect: community.general.rundeck_project
utm_aaa_group:
redirect: community.general.utm_aaa_group
utm_aaa_group_info:
redirect: community.general.utm_aaa_group_info
utm_ca_host_key_cert:
redirect: community.general.utm_ca_host_key_cert
utm_ca_host_key_cert_info:
redirect: community.general.utm_ca_host_key_cert_info
utm_dns_host:
redirect: community.general.utm_dns_host
utm_network_interface_address:
redirect: community.general.utm_network_interface_address
utm_network_interface_address_info:
redirect: community.general.utm_network_interface_address_info
utm_proxy_auth_profile:
redirect: community.general.utm_proxy_auth_profile
utm_proxy_exception:
redirect: community.general.utm_proxy_exception
utm_proxy_frontend:
redirect: community.general.utm_proxy_frontend
utm_proxy_frontend_info:
redirect: community.general.utm_proxy_frontend_info
utm_proxy_location:
redirect: community.general.utm_proxy_location
utm_proxy_location_info:
redirect: community.general.utm_proxy_location_info
supervisorctl:
redirect: community.general.supervisorctl
taiga_issue:
redirect: community.general.taiga_issue
grafana_dashboard:
redirect: community.grafana.grafana_dashboard
grafana_datasource:
redirect: community.grafana.grafana_datasource
grafana_plugin:
redirect: community.grafana.grafana_plugin
k8s_facts:
redirect: kubernetes.core.k8s_facts
k8s_raw:
redirect: kubernetes.core.k8s_raw
k8s:
redirect: kubernetes.core.k8s
k8s_auth:
redirect: kubernetes.core.k8s_auth
k8s_info:
redirect: kubernetes.core.k8s_info
k8s_scale:
redirect: kubernetes.core.k8s_scale
k8s_service:
redirect: kubernetes.core.k8s_service
openshift_raw:
redirect: kubernetes.core.openshift_raw
openshift_scale:
redirect: kubernetes.core.openshift_scale
openssh_cert:
redirect: community.crypto.openssh_cert
openssl_pkcs12:
redirect: community.crypto.openssl_pkcs12
openssl_csr:
redirect: community.crypto.openssl_csr
openssl_certificate:
redirect: community.crypto.x509_certificate
openssl_certificate_info:
redirect: community.crypto.x509_certificate_info
x509_crl:
redirect: community.crypto.x509_crl
openssl_privatekey_info:
redirect: community.crypto.openssl_privatekey_info
x509_crl_info:
redirect: community.crypto.x509_crl_info
get_certificate:
redirect: community.crypto.get_certificate
openssh_keypair:
redirect: community.crypto.openssh_keypair
openssl_publickey:
redirect: community.crypto.openssl_publickey
openssl_csr_info:
redirect: community.crypto.openssl_csr_info
luks_device:
redirect: community.crypto.luks_device
openssl_dhparam:
redirect: community.crypto.openssl_dhparam
openssl_privatekey:
redirect: community.crypto.openssl_privatekey
certificate_complete_chain:
redirect: community.crypto.certificate_complete_chain
acme_inspect:
redirect: community.crypto.acme_inspect
acme_certificate_revoke:
redirect: community.crypto.acme_certificate_revoke
acme_certificate:
redirect: community.crypto.acme_certificate
acme_account:
redirect: community.crypto.acme_account
acme_account_facts:
redirect: community.crypto.acme_account_facts
acme_challenge_cert_helper:
redirect: community.crypto.acme_challenge_cert_helper
acme_account_info:
redirect: community.crypto.acme_account_info
ecs_domain:
redirect: community.crypto.ecs_domain
ecs_certificate:
redirect: community.crypto.ecs_certificate
mongodb_parameter:
redirect: community.mongodb.mongodb_parameter
mongodb_info:
redirect: community.mongodb.mongodb_info
mongodb_replicaset:
redirect: community.mongodb.mongodb_replicaset
mongodb_user:
redirect: community.mongodb.mongodb_user
mongodb_shard:
redirect: community.mongodb.mongodb_shard
vmware_appliance_access_info:
redirect: vmware.vmware_rest.vmware_appliance_access_info
vmware_appliance_health_info:
redirect: vmware.vmware_rest.vmware_appliance_health_info
vmware_cis_category_info:
redirect: vmware.vmware_rest.vmware_cis_category_info
vmware_core_info:
redirect: vmware.vmware_rest.vmware_core_info
vcenter_extension_facts:
redirect: community.vmware.vcenter_extension_facts
vmware_about_facts:
redirect: community.vmware.vmware_about_facts
vmware_category_facts:
redirect: community.vmware.vmware_category_facts
vmware_cluster_facts:
redirect: community.vmware.vmware_cluster_facts
vmware_datastore_facts:
redirect: community.vmware.vmware_datastore_facts
vmware_dns_config:
redirect: community.vmware.vmware_dns_config
vmware_drs_group_facts:
redirect: community.vmware.vmware_drs_group_facts
vmware_drs_rule_facts:
redirect: community.vmware.vmware_drs_rule_facts
vmware_dvs_portgroup_facts:
redirect: community.vmware.vmware_dvs_portgroup_facts
vmware_guest_boot_facts:
redirect: community.vmware.vmware_guest_boot_facts
vmware_guest_customization_facts:
redirect: community.vmware.vmware_guest_customization_facts
vmware_guest_disk_facts:
redirect: community.vmware.vmware_guest_disk_facts
vmware_guest_facts:
redirect: community.vmware.vmware_guest_facts
vmware_guest_snapshot_facts:
redirect: community.vmware.vmware_guest_snapshot_facts
vmware_host_capability_facts:
redirect: community.vmware.vmware_host_capability_facts
vmware_host_config_facts:
redirect: community.vmware.vmware_host_config_facts
vmware_host_dns_facts:
redirect: community.vmware.vmware_host_dns_facts
vmware_host_feature_facts:
redirect: community.vmware.vmware_host_feature_facts
vmware_host_firewall_facts:
redirect: community.vmware.vmware_host_firewall_facts
vmware_host_ntp_facts:
redirect: community.vmware.vmware_host_ntp_facts
vmware_host_package_facts:
redirect: community.vmware.vmware_host_package_facts
vmware_host_service_facts:
redirect: community.vmware.vmware_host_service_facts
vmware_host_ssl_facts:
redirect: community.vmware.vmware_host_ssl_facts
vmware_host_vmhba_facts:
redirect: community.vmware.vmware_host_vmhba_facts
vmware_host_vmnic_facts:
redirect: community.vmware.vmware_host_vmnic_facts
vmware_local_role_facts:
redirect: community.vmware.vmware_local_role_facts
vmware_local_user_facts:
redirect: community.vmware.vmware_local_user_facts
vmware_portgroup_facts:
redirect: community.vmware.vmware_portgroup_facts
vmware_resource_pool_facts:
redirect: community.vmware.vmware_resource_pool_facts
vmware_tag_facts:
redirect: community.vmware.vmware_tag_facts
vmware_target_canonical_facts:
redirect: community.vmware.vmware_target_canonical_facts
vmware_vm_facts:
redirect: community.vmware.vmware_vm_facts
vmware_vmkernel_facts:
redirect: community.vmware.vmware_vmkernel_facts
vmware_vswitch_facts:
redirect: community.vmware.vmware_vswitch_facts
vca_fw:
redirect: community.vmware.vca_fw
vca_nat:
redirect: community.vmware.vca_nat
vca_vapp:
redirect: community.vmware.vca_vapp
vcenter_extension:
redirect: community.vmware.vcenter_extension
vcenter_extension_info:
redirect: community.vmware.vcenter_extension_info
vcenter_folder:
redirect: community.vmware.vcenter_folder
vcenter_license:
redirect: community.vmware.vcenter_license
vmware_about_info:
redirect: community.vmware.vmware_about_info
vmware_category:
redirect: community.vmware.vmware_category
vmware_category_info:
redirect: community.vmware.vmware_category_info
vmware_cfg_backup:
redirect: community.vmware.vmware_cfg_backup
vmware_cluster:
redirect: community.vmware.vmware_cluster
vmware_cluster_drs:
redirect: community.vmware.vmware_cluster_drs
vmware_cluster_ha:
redirect: community.vmware.vmware_cluster_ha
vmware_cluster_info:
redirect: community.vmware.vmware_cluster_info
vmware_cluster_vsan:
redirect: community.vmware.vmware_cluster_vsan
vmware_content_deploy_template:
redirect: community.vmware.vmware_content_deploy_template
vmware_content_library_info:
redirect: community.vmware.vmware_content_library_info
vmware_content_library_manager:
redirect: community.vmware.vmware_content_library_manager
vmware_datacenter:
redirect: community.vmware.vmware_datacenter
vmware_datastore_cluster:
redirect: community.vmware.vmware_datastore_cluster
vmware_datastore_info:
redirect: community.vmware.vmware_datastore_info
vmware_datastore_maintenancemode:
redirect: community.vmware.vmware_datastore_maintenancemode
vmware_deploy_ovf:
redirect: community.vmware.vmware_deploy_ovf
vmware_drs_group:
redirect: community.vmware.vmware_drs_group
vmware_drs_group_info:
redirect: community.vmware.vmware_drs_group_info
vmware_drs_rule_info:
redirect: community.vmware.vmware_drs_rule_info
vmware_dvs_host:
redirect: community.vmware.vmware_dvs_host
vmware_dvs_portgroup:
redirect: community.vmware.vmware_dvs_portgroup
vmware_dvs_portgroup_find:
redirect: community.vmware.vmware_dvs_portgroup_find
vmware_dvs_portgroup_info:
redirect: community.vmware.vmware_dvs_portgroup_info
vmware_dvswitch:
redirect: community.vmware.vmware_dvswitch
vmware_dvswitch_lacp:
redirect: community.vmware.vmware_dvswitch_lacp
vmware_dvswitch_nioc:
redirect: community.vmware.vmware_dvswitch_nioc
vmware_dvswitch_pvlans:
redirect: community.vmware.vmware_dvswitch_pvlans
vmware_dvswitch_uplink_pg:
redirect: community.vmware.vmware_dvswitch_uplink_pg
vmware_evc_mode:
redirect: community.vmware.vmware_evc_mode
vmware_export_ovf:
redirect: community.vmware.vmware_export_ovf
vmware_folder_info:
redirect: community.vmware.vmware_folder_info
vmware_guest:
redirect: community.vmware.vmware_guest
vmware_guest_boot_info:
redirect: community.vmware.vmware_guest_boot_info
vmware_guest_boot_manager:
redirect: community.vmware.vmware_guest_boot_manager
vmware_guest_controller:
redirect: community.vmware.vmware_guest_controller
vmware_guest_cross_vc_clone:
redirect: community.vmware.vmware_guest_cross_vc_clone
vmware_guest_custom_attribute_defs:
redirect: community.vmware.vmware_guest_custom_attribute_defs
vmware_guest_custom_attributes:
redirect: community.vmware.vmware_guest_custom_attributes
vmware_guest_customization_info:
redirect: community.vmware.vmware_guest_customization_info
vmware_guest_disk:
redirect: community.vmware.vmware_guest_disk
vmware_guest_disk_info:
redirect: community.vmware.vmware_guest_disk_info
vmware_guest_file_operation:
redirect: community.vmware.vmware_guest_file_operation
vmware_guest_find:
redirect: community.vmware.vmware_guest_find
vmware_guest_info:
redirect: community.vmware.vmware_guest_info
vmware_guest_move:
redirect: community.vmware.vmware_guest_move
vmware_guest_network:
redirect: community.vmware.vmware_guest_network
vmware_guest_powerstate:
redirect: community.vmware.vmware_guest_powerstate
vmware_guest_register_operation:
redirect: community.vmware.vmware_guest_register_operation
vmware_guest_screenshot:
redirect: community.vmware.vmware_guest_screenshot
vmware_guest_sendkey:
redirect: community.vmware.vmware_guest_sendkey
vmware_guest_serial_port:
redirect: community.vmware.vmware_guest_serial_port
vmware_guest_snapshot:
redirect: community.vmware.vmware_guest_snapshot
vmware_guest_snapshot_info:
redirect: community.vmware.vmware_guest_snapshot_info
vmware_guest_tools_info:
redirect: community.vmware.vmware_guest_tools_info
vmware_guest_tools_upgrade:
redirect: community.vmware.vmware_guest_tools_upgrade
vmware_guest_tools_wait:
redirect: community.vmware.vmware_guest_tools_wait
vmware_guest_video:
redirect: community.vmware.vmware_guest_video
vmware_guest_vnc:
redirect: community.vmware.vmware_guest_vnc
vmware_host:
redirect: community.vmware.vmware_host
vmware_host_acceptance:
redirect: community.vmware.vmware_host_acceptance
vmware_host_active_directory:
redirect: community.vmware.vmware_host_active_directory
vmware_host_auto_start:
redirect: community.vmware.vmware_host_auto_start
vmware_host_capability_info:
redirect: community.vmware.vmware_host_capability_info
vmware_host_config_info:
redirect: community.vmware.vmware_host_config_info
vmware_host_config_manager:
redirect: community.vmware.vmware_host_config_manager
vmware_host_datastore:
redirect: community.vmware.vmware_host_datastore
vmware_host_dns:
redirect: community.vmware.vmware_host_dns
vmware_host_dns_info:
redirect: community.vmware.vmware_host_dns_info
vmware_host_facts:
redirect: community.vmware.vmware_host_facts
vmware_host_feature_info:
redirect: community.vmware.vmware_host_feature_info
vmware_host_firewall_info:
redirect: community.vmware.vmware_host_firewall_info
vmware_host_firewall_manager:
redirect: community.vmware.vmware_host_firewall_manager
vmware_host_hyperthreading:
redirect: community.vmware.vmware_host_hyperthreading
vmware_host_ipv6:
redirect: community.vmware.vmware_host_ipv6
vmware_host_kernel_manager:
redirect: community.vmware.vmware_host_kernel_manager
vmware_host_lockdown:
redirect: community.vmware.vmware_host_lockdown
vmware_host_ntp:
redirect: community.vmware.vmware_host_ntp
vmware_host_ntp_info:
redirect: community.vmware.vmware_host_ntp_info
vmware_host_package_info:
redirect: community.vmware.vmware_host_package_info
vmware_host_powermgmt_policy:
redirect: community.vmware.vmware_host_powermgmt_policy
vmware_host_powerstate:
redirect: community.vmware.vmware_host_powerstate
vmware_host_scanhba:
redirect: community.vmware.vmware_host_scanhba
vmware_host_service_info:
redirect: community.vmware.vmware_host_service_info
vmware_host_service_manager:
redirect: community.vmware.vmware_host_service_manager
vmware_host_snmp:
redirect: community.vmware.vmware_host_snmp
vmware_host_ssl_info:
redirect: community.vmware.vmware_host_ssl_info
vmware_host_vmhba_info:
redirect: community.vmware.vmware_host_vmhba_info
vmware_host_vmnic_info:
redirect: community.vmware.vmware_host_vmnic_info
vmware_local_role_info:
redirect: community.vmware.vmware_local_role_info
vmware_local_role_manager:
redirect: community.vmware.vmware_local_role_manager
vmware_local_user_info:
redirect: community.vmware.vmware_local_user_info
vmware_local_user_manager:
redirect: community.vmware.vmware_local_user_manager
vmware_maintenancemode:
redirect: community.vmware.vmware_maintenancemode
vmware_migrate_vmk:
redirect: community.vmware.vmware_migrate_vmk
vmware_object_role_permission:
redirect: community.vmware.vmware_object_role_permission
vmware_portgroup:
redirect: community.vmware.vmware_portgroup
vmware_portgroup_info:
redirect: community.vmware.vmware_portgroup_info
vmware_resource_pool:
redirect: community.vmware.vmware_resource_pool
vmware_resource_pool_info:
redirect: community.vmware.vmware_resource_pool_info
vmware_tag:
redirect: community.vmware.vmware_tag
vmware_tag_info:
redirect: community.vmware.vmware_tag_info
vmware_tag_manager:
redirect: community.vmware.vmware_tag_manager
vmware_target_canonical_info:
redirect: community.vmware.vmware_target_canonical_info
vmware_vcenter_settings:
redirect: community.vmware.vmware_vcenter_settings
vmware_vcenter_statistics:
redirect: community.vmware.vmware_vcenter_statistics
vmware_vm_host_drs_rule:
redirect: community.vmware.vmware_vm_host_drs_rule
vmware_vm_info:
redirect: community.vmware.vmware_vm_info
vmware_vm_shell:
redirect: community.vmware.vmware_vm_shell
vmware_vm_storage_policy_info:
redirect: community.vmware.vmware_vm_storage_policy_info
vmware_vm_vm_drs_rule:
redirect: community.vmware.vmware_vm_vm_drs_rule
vmware_vm_vss_dvs_migrate:
redirect: community.vmware.vmware_vm_vss_dvs_migrate
vmware_vmkernel:
redirect: community.vmware.vmware_vmkernel
vmware_vmkernel_info:
redirect: community.vmware.vmware_vmkernel_info
vmware_vmkernel_ip_config:
redirect: community.vmware.vmware_vmkernel_ip_config
vmware_vmotion:
redirect: community.vmware.vmware_vmotion
vmware_vsan_cluster:
redirect: community.vmware.vmware_vsan_cluster
vmware_vsan_health_info:
redirect: community.vmware.vmware_vsan_health_info
vmware_vspan_session:
redirect: community.vmware.vmware_vspan_session
vmware_vswitch:
redirect: community.vmware.vmware_vswitch
vmware_vswitch_info:
redirect: community.vmware.vmware_vswitch_info
vsphere_copy:
redirect: community.vmware.vsphere_copy
vsphere_file:
redirect: community.vmware.vsphere_file
psexec:
redirect: community.windows.psexec
win_audit_policy_system:
redirect: community.windows.win_audit_policy_system
win_audit_rule:
redirect: community.windows.win_audit_rule
win_chocolatey:
redirect: chocolatey.chocolatey.win_chocolatey
win_chocolatey_config:
redirect: chocolatey.chocolatey.win_chocolatey_config
win_chocolatey_facts:
redirect: chocolatey.chocolatey.win_chocolatey_facts
win_chocolatey_feature:
redirect: chocolatey.chocolatey.win_chocolatey_feature
win_chocolatey_source:
redirect: chocolatey.chocolatey.win_chocolatey_source
win_credential:
redirect: community.windows.win_credential
win_defrag:
redirect: community.windows.win_defrag
win_disk_facts:
redirect: community.windows.win_disk_facts
win_disk_image:
redirect: community.windows.win_disk_image
win_dns_record:
redirect: community.windows.win_dns_record
win_domain_computer:
redirect: community.windows.win_domain_computer
win_domain_group:
redirect: community.windows.win_domain_group
win_domain_group_membership:
redirect: community.windows.win_domain_group_membership
win_domain_user:
redirect: community.windows.win_domain_user
win_dotnet_ngen:
redirect: community.windows.win_dotnet_ngen
win_eventlog:
redirect: community.windows.win_eventlog
win_eventlog_entry:
redirect: community.windows.win_eventlog_entry
win_file_version:
redirect: community.windows.win_file_version
win_firewall:
redirect: community.windows.win_firewall
win_firewall_rule:
redirect: community.windows.win_firewall_rule
win_format:
redirect: community.windows.win_format
win_hosts:
redirect: community.windows.win_hosts
win_hotfix:
redirect: community.windows.win_hotfix
win_http_proxy:
redirect: community.windows.win_http_proxy
win_iis_virtualdirectory:
redirect: community.windows.win_iis_virtualdirectory
win_iis_webapplication:
redirect: community.windows.win_iis_webapplication
win_iis_webapppool:
redirect: community.windows.win_iis_webapppool
win_iis_webbinding:
redirect: community.windows.win_iis_webbinding
win_iis_website:
redirect: community.windows.win_iis_website
win_inet_proxy:
redirect: community.windows.win_inet_proxy
win_initialize_disk:
redirect: community.windows.win_initialize_disk
win_lineinfile:
redirect: community.windows.win_lineinfile
win_mapped_drive:
redirect: community.windows.win_mapped_drive
win_msg:
redirect: community.windows.win_msg
win_netbios:
redirect: community.windows.win_netbios
win_nssm:
redirect: community.windows.win_nssm
win_pagefile:
redirect: community.windows.win_pagefile
win_partition:
redirect: community.windows.win_partition
win_pester:
redirect: community.windows.win_pester
win_power_plan:
redirect: community.windows.win_power_plan
win_product_facts:
redirect: community.windows.win_product_facts
win_psexec:
redirect: community.windows.win_psexec
win_psmodule:
redirect: community.windows.win_psmodule
win_psrepository:
redirect: community.windows.win_psrepository
win_rabbitmq_plugin:
redirect: community.windows.win_rabbitmq_plugin
win_rds_cap:
redirect: community.windows.win_rds_cap
win_rds_rap:
redirect: community.windows.win_rds_rap
win_rds_settings:
redirect: community.windows.win_rds_settings
win_region:
redirect: community.windows.win_region
win_regmerge:
redirect: community.windows.win_regmerge
win_robocopy:
redirect: community.windows.win_robocopy
win_route:
redirect: community.windows.win_route
win_say:
redirect: community.windows.win_say
win_scheduled_task:
redirect: community.windows.win_scheduled_task
win_scheduled_task_stat:
redirect: community.windows.win_scheduled_task_stat
win_security_policy:
redirect: community.windows.win_security_policy
win_shortcut:
redirect: community.windows.win_shortcut
win_snmp:
redirect: community.windows.win_snmp
win_timezone:
redirect: community.windows.win_timezone
win_toast:
redirect: community.windows.win_toast
win_unzip:
redirect: community.windows.win_unzip
win_user_profile:
redirect: community.windows.win_user_profile
win_wait_for_process:
redirect: community.windows.win_wait_for_process
win_wakeonlan:
redirect: community.windows.win_wakeonlan
win_webpicmd:
redirect: community.windows.win_webpicmd
win_xml:
redirect: community.windows.win_xml
azure_rm_aks_facts:
redirect: community.azure.azure_rm_aks_facts
azure_rm_dnsrecordset_facts:
redirect: community.azure.azure_rm_dnsrecordset_facts
azure_rm_dnszone_facts:
redirect: community.azure.azure_rm_dnszone_facts
azure_rm_networkinterface_facts:
redirect: community.azure.azure_rm_networkinterface_facts
azure_rm_publicipaddress_facts:
redirect: community.azure.azure_rm_publicipaddress_facts
azure_rm_securitygroup_facts:
redirect: community.azure.azure_rm_securitygroup_facts
azure_rm_storageaccount_facts:
redirect: community.azure.azure_rm_storageaccount_facts
azure_rm_virtualmachine_facts:
redirect: community.azure.azure_rm_virtualmachine_facts
azure_rm_virtualnetwork_facts:
redirect: community.azure.azure_rm_virtualnetwork_facts
azure_rm_roledefinition_facts:
redirect: community.azure.azure_rm_roledefinition_facts
azure_rm_autoscale_facts:
redirect: community.azure.azure_rm_autoscale_facts
azure_rm_mysqldatabase_facts:
redirect: community.azure.azure_rm_mysqldatabase_facts
azure_rm_devtestlabschedule_facts:
redirect: community.azure.azure_rm_devtestlabschedule_facts
azure_rm_virtualmachinescaleset_facts:
redirect: community.azure.azure_rm_virtualmachinescaleset_facts
azure_rm_devtestlabcustomimage_facts:
redirect: community.azure.azure_rm_devtestlabcustomimage_facts
azure_rm_cosmosdbaccount_facts:
redirect: community.azure.azure_rm_cosmosdbaccount_facts
azure_rm_subnet_facts:
redirect: community.azure.azure_rm_subnet_facts
azure_rm_aksversion_facts:
redirect: community.azure.azure_rm_aksversion_facts
azure_rm_hdinsightcluster_facts:
redirect: community.azure.azure_rm_hdinsightcluster_facts
azure_rm_virtualmachinescalesetextension_facts:
redirect: community.azure.azure_rm_virtualmachinescalesetextension_facts
azure_rm_loadbalancer_facts:
redirect: community.azure.azure_rm_loadbalancer_facts
azure_rm_roleassignment_facts:
redirect: community.azure.azure_rm_roleassignment_facts
azure_rm_manageddisk_facts:
redirect: community.azure.azure_rm_manageddisk_facts
azure_rm_mysqlserver_facts:
redirect: community.azure.azure_rm_mysqlserver_facts
azure_rm_servicebus_facts:
redirect: community.azure.azure_rm_servicebus_facts
azure_rm_rediscache_facts:
redirect: community.azure.azure_rm_rediscache_facts
azure_rm_resource_facts:
redirect: community.azure.azure_rm_resource_facts
azure_rm_routetable_facts:
redirect: community.azure.azure_rm_routetable_facts
azure_rm_virtualmachine_extension:
redirect: community.azure.azure_rm_virtualmachine_extension
azure_rm_loganalyticsworkspace_facts:
redirect: community.azure.azure_rm_loganalyticsworkspace_facts
azure_rm_sqldatabase_facts:
redirect: community.azure.azure_rm_sqldatabase_facts
azure_rm_devtestlabartifactsource_facts:
redirect: community.azure.azure_rm_devtestlabartifactsource_facts
azure_rm_deployment_facts:
redirect: community.azure.azure_rm_deployment_facts
azure_rm_virtualmachineextension_facts:
redirect: community.azure.azure_rm_virtualmachineextension_facts
azure_rm_applicationsecuritygroup_facts:
redirect: community.azure.azure_rm_applicationsecuritygroup_facts
azure_rm_availabilityset_facts:
redirect: community.azure.azure_rm_availabilityset_facts
azure_rm_mariadbdatabase_facts:
redirect: community.azure.azure_rm_mariadbdatabase_facts
azure_rm_devtestlabenvironment_facts:
redirect: community.azure.azure_rm_devtestlabenvironment_facts
azure_rm_appserviceplan_facts:
redirect: community.azure.azure_rm_appserviceplan_facts
azure_rm_containerinstance_facts:
redirect: community.azure.azure_rm_containerinstance_facts
azure_rm_devtestlabarmtemplate_facts:
redirect: community.azure.azure_rm_devtestlabarmtemplate_facts
azure_rm_devtestlabartifact_facts:
redirect: community.azure.azure_rm_devtestlabartifact_facts
azure_rm_virtualmachinescalesetinstance_facts:
redirect: community.azure.azure_rm_virtualmachinescalesetinstance_facts
azure_rm_cdnendpoint_facts:
redirect: community.azure.azure_rm_cdnendpoint_facts
azure_rm_trafficmanagerprofile_facts:
redirect: community.azure.azure_rm_trafficmanagerprofile_facts
azure_rm_functionapp_facts:
redirect: community.azure.azure_rm_functionapp_facts
azure_rm_virtualmachineimage_facts:
redirect: community.azure.azure_rm_virtualmachineimage_facts
azure_rm_mariadbconfiguration_facts:
redirect: community.azure.azure_rm_mariadbconfiguration_facts
azure_rm_virtualnetworkpeering_facts:
redirect: community.azure.azure_rm_virtualnetworkpeering_facts
azure_rm_sqlserver_facts:
redirect: community.azure.azure_rm_sqlserver_facts
azure_rm_mariadbfirewallrule_facts:
redirect: community.azure.azure_rm_mariadbfirewallrule_facts
azure_rm_mysqlconfiguration_facts:
redirect: community.azure.azure_rm_mysqlconfiguration_facts
azure_rm_mysqlfirewallrule_facts:
redirect: community.azure.azure_rm_mysqlfirewallrule_facts
azure_rm_postgresqlfirewallrule_facts:
redirect: community.azure.azure_rm_postgresqlfirewallrule_facts
azure_rm_mariadbserver_facts:
redirect: community.azure.azure_rm_mariadbserver_facts
azure_rm_postgresqldatabase_facts:
redirect: community.azure.azure_rm_postgresqldatabase_facts
azure_rm_devtestlabvirtualnetwork_facts:
redirect: community.azure.azure_rm_devtestlabvirtualnetwork_facts
azure_rm_devtestlabpolicy_facts:
redirect: community.azure.azure_rm_devtestlabpolicy_facts
azure_rm_trafficmanagerendpoint_facts:
redirect: community.azure.azure_rm_trafficmanagerendpoint_facts
azure_rm_sqlfirewallrule_facts:
redirect: community.azure.azure_rm_sqlfirewallrule_facts
azure_rm_containerregistry_facts:
redirect: community.azure.azure_rm_containerregistry_facts
azure_rm_postgresqlconfiguration_facts:
redirect: community.azure.azure_rm_postgresqlconfiguration_facts
azure_rm_postgresqlserver_facts:
redirect: community.azure.azure_rm_postgresqlserver_facts
azure_rm_devtestlab_facts:
redirect: community.azure.azure_rm_devtestlab_facts
azure_rm_cdnprofile_facts:
redirect: community.azure.azure_rm_cdnprofile_facts
azure_rm_virtualmachine_scaleset:
redirect: community.azure.azure_rm_virtualmachine_scaleset
azure_rm_webapp_facts:
redirect: community.azure.azure_rm_webapp_facts
azure_rm_devtestlabvirtualmachine_facts:
redirect: community.azure.azure_rm_devtestlabvirtualmachine_facts
azure_rm_image_facts:
redirect: community.azure.azure_rm_image_facts
azure_rm_managed_disk:
redirect: community.azure.azure_rm_managed_disk
azure_rm_automationaccount_facts:
redirect: community.azure.azure_rm_automationaccount_facts
azure_rm_lock_facts:
redirect: community.azure.azure_rm_lock_facts
azure_rm_managed_disk_facts:
redirect: community.azure.azure_rm_managed_disk_facts
azure_rm_resourcegroup_facts:
redirect: community.azure.azure_rm_resourcegroup_facts
azure_rm_virtualmachine_scaleset_facts:
redirect: community.azure.azure_rm_virtualmachine_scaleset_facts
snow_record:
redirect: servicenow.servicenow.snow_record
snow_record_find:
redirect: servicenow.servicenow.snow_record_find
aws_az_facts:
redirect: amazon.aws.aws_az_facts
aws_caller_facts:
redirect: amazon.aws.aws_caller_facts
cloudformation_facts:
redirect: amazon.aws.cloudformation_facts
ec2_ami_facts:
redirect: amazon.aws.ec2_ami_facts
ec2_eni_facts:
redirect: amazon.aws.ec2_eni_facts
ec2_group_facts:
redirect: amazon.aws.ec2_group_facts
ec2_snapshot_facts:
redirect: amazon.aws.ec2_snapshot_facts
ec2_vol_facts:
redirect: amazon.aws.ec2_vol_facts
ec2_vpc_dhcp_option_facts:
redirect: amazon.aws.ec2_vpc_dhcp_option_facts
ec2_vpc_net_facts:
redirect: amazon.aws.ec2_vpc_net_facts
ec2_vpc_subnet_facts:
redirect: amazon.aws.ec2_vpc_subnet_facts
aws_az_info:
redirect: amazon.aws.aws_az_info
aws_caller_info:
redirect: amazon.aws.aws_caller_info
aws_s3:
redirect: amazon.aws.aws_s3
cloudformation:
redirect: amazon.aws.cloudformation
cloudformation_info:
redirect: amazon.aws.cloudformation_info
ec2:
redirect: amazon.aws.ec2
ec2_ami:
redirect: amazon.aws.ec2_ami
ec2_ami_info:
redirect: amazon.aws.ec2_ami_info
ec2_elb_lb:
redirect: amazon.aws.ec2_elb_lb
ec2_eni:
redirect: amazon.aws.ec2_eni
ec2_eni_info:
redirect: amazon.aws.ec2_eni_info
ec2_group:
redirect: amazon.aws.ec2_group
ec2_group_info:
redirect: amazon.aws.ec2_group_info
ec2_key:
redirect: amazon.aws.ec2_key
ec2_metadata_facts:
redirect: amazon.aws.ec2_metadata_facts
ec2_snapshot:
redirect: amazon.aws.ec2_snapshot
ec2_snapshot_info:
redirect: amazon.aws.ec2_snapshot_info
ec2_tag:
redirect: amazon.aws.ec2_tag
ec2_tag_info:
redirect: amazon.aws.ec2_tag_info
ec2_vol:
redirect: amazon.aws.ec2_vol
ec2_vol_info:
redirect: amazon.aws.ec2_vol_info
ec2_vpc_dhcp_option:
redirect: amazon.aws.ec2_vpc_dhcp_option
ec2_vpc_dhcp_option_info:
redirect: amazon.aws.ec2_vpc_dhcp_option_info
ec2_vpc_net:
redirect: amazon.aws.ec2_vpc_net
ec2_vpc_net_info:
redirect: amazon.aws.ec2_vpc_net_info
ec2_vpc_subnet:
redirect: amazon.aws.ec2_vpc_subnet
ec2_vpc_subnet_info:
redirect: amazon.aws.ec2_vpc_subnet_info
s3_bucket:
redirect: amazon.aws.s3_bucket
telnet:
redirect: ansible.netcommon.telnet
cli_command:
redirect: ansible.netcommon.cli_command
cli_config:
redirect: ansible.netcommon.cli_config
net_put:
redirect: ansible.netcommon.net_put
net_get:
redirect: ansible.netcommon.net_get
net_linkagg:
redirect: ansible.netcommon.net_linkagg
net_interface:
redirect: ansible.netcommon.net_interface
net_lldp_interface:
redirect: ansible.netcommon.net_lldp_interface
net_vlan:
redirect: ansible.netcommon.net_vlan
net_l2_interface:
redirect: ansible.netcommon.net_l2_interface
net_l3_interface:
redirect: ansible.netcommon.net_l3_interface
net_vrf:
redirect: ansible.netcommon.net_vrf
netconf_config:
redirect: ansible.netcommon.netconf_config
netconf_rpc:
redirect: ansible.netcommon.netconf_rpc
netconf_get:
redirect: ansible.netcommon.netconf_get
net_lldp:
redirect: ansible.netcommon.net_lldp
restconf_get:
redirect: ansible.netcommon.restconf_get
restconf_config:
redirect: ansible.netcommon.restconf_config
net_static_route:
redirect: ansible.netcommon.net_static_route
net_system:
redirect: ansible.netcommon.net_system
net_logging:
redirect: ansible.netcommon.net_logging
net_user:
redirect: ansible.netcommon.net_user
net_ping:
redirect: ansible.netcommon.net_ping
net_banner:
redirect: ansible.netcommon.net_banner
acl:
redirect: ansible.posix.acl
synchronize:
redirect: ansible.posix.synchronize
at:
redirect: ansible.posix.at
authorized_key:
redirect: ansible.posix.authorized_key
mount:
redirect: ansible.posix.mount
seboolean:
redirect: ansible.posix.seboolean
selinux:
redirect: ansible.posix.selinux
sysctl:
redirect: ansible.posix.sysctl
async_status.ps1:
redirect: ansible.windows.async_status
setup.ps1:
redirect: ansible.windows.setup
slurp.ps1:
redirect: ansible.windows.slurp
win_acl:
redirect: ansible.windows.win_acl
win_acl_inheritance:
redirect: ansible.windows.win_acl_inheritance
win_certificate_store:
redirect: ansible.windows.win_certificate_store
win_command:
redirect: ansible.windows.win_command
win_copy:
redirect: ansible.windows.win_copy
win_dns_client:
redirect: ansible.windows.win_dns_client
win_domain:
redirect: ansible.windows.win_domain
win_domain_controller:
redirect: ansible.windows.win_domain_controller
win_domain_membership:
redirect: ansible.windows.win_domain_membership
win_dsc:
redirect: ansible.windows.win_dsc
win_environment:
redirect: ansible.windows.win_environment
win_feature:
redirect: ansible.windows.win_feature
win_file:
redirect: ansible.windows.win_file
win_find:
redirect: ansible.windows.win_find
win_get_url:
redirect: ansible.windows.win_get_url
win_group:
redirect: ansible.windows.win_group
win_group_membership:
redirect: ansible.windows.win_group_membership
win_hostname:
redirect: ansible.windows.win_hostname
win_optional_feature:
redirect: ansible.windows.win_optional_feature
win_owner:
redirect: ansible.windows.win_owner
win_package:
redirect: ansible.windows.win_package
win_path:
redirect: ansible.windows.win_path
win_ping:
redirect: ansible.windows.win_ping
win_reboot:
redirect: ansible.windows.win_reboot
win_reg_stat:
redirect: ansible.windows.win_reg_stat
win_regedit:
redirect: ansible.windows.win_regedit
win_service:
redirect: ansible.windows.win_service
win_share:
redirect: ansible.windows.win_share
win_shell:
redirect: ansible.windows.win_shell
win_stat:
redirect: ansible.windows.win_stat
win_tempfile:
redirect: ansible.windows.win_tempfile
win_template:
redirect: ansible.windows.win_template
win_updates:
redirect: ansible.windows.win_updates
win_uri:
redirect: ansible.windows.win_uri
win_user:
redirect: ansible.windows.win_user
win_user_right:
redirect: ansible.windows.win_user_right
win_wait_for:
redirect: ansible.windows.win_wait_for
win_whoami:
redirect: ansible.windows.win_whoami
fortios_address:
redirect: fortinet.fortios.fortios_address
fortios_alertemail_setting:
redirect: fortinet.fortios.fortios_alertemail_setting
fortios_antivirus_heuristic:
redirect: fortinet.fortios.fortios_antivirus_heuristic
fortios_antivirus_profile:
redirect: fortinet.fortios.fortios_antivirus_profile
fortios_antivirus_quarantine:
redirect: fortinet.fortios.fortios_antivirus_quarantine
fortios_antivirus_settings:
redirect: fortinet.fortios.fortios_antivirus_settings
fortios_application_custom:
redirect: fortinet.fortios.fortios_application_custom
fortios_application_group:
redirect: fortinet.fortios.fortios_application_group
fortios_application_list:
redirect: fortinet.fortios.fortios_application_list
fortios_application_name:
redirect: fortinet.fortios.fortios_application_name
fortios_application_rule_settings:
redirect: fortinet.fortios.fortios_application_rule_settings
fortios_authentication_rule:
redirect: fortinet.fortios.fortios_authentication_rule
fortios_authentication_scheme:
redirect: fortinet.fortios.fortios_authentication_scheme
fortios_authentication_setting:
redirect: fortinet.fortios.fortios_authentication_setting
fortios_config:
redirect: fortinet.fortios.fortios_config
fortios_dlp_filepattern:
redirect: fortinet.fortios.fortios_dlp_filepattern
fortios_dlp_fp_doc_source:
redirect: fortinet.fortios.fortios_dlp_fp_doc_source
fortios_dlp_fp_sensitivity:
redirect: fortinet.fortios.fortios_dlp_fp_sensitivity
fortios_dlp_sensor:
redirect: fortinet.fortios.fortios_dlp_sensor
fortios_dlp_settings:
redirect: fortinet.fortios.fortios_dlp_settings
fortios_dnsfilter_domain_filter:
redirect: fortinet.fortios.fortios_dnsfilter_domain_filter
fortios_dnsfilter_profile:
redirect: fortinet.fortios.fortios_dnsfilter_profile
fortios_endpoint_control_client:
redirect: fortinet.fortios.fortios_endpoint_control_client
fortios_endpoint_control_forticlient_ems:
redirect: fortinet.fortios.fortios_endpoint_control_forticlient_ems
fortios_endpoint_control_forticlient_registration_sync:
redirect: fortinet.fortios.fortios_endpoint_control_forticlient_registration_sync
fortios_endpoint_control_profile:
redirect: fortinet.fortios.fortios_endpoint_control_profile
fortios_endpoint_control_settings:
redirect: fortinet.fortios.fortios_endpoint_control_settings
fortios_extender_controller_extender:
redirect: fortinet.fortios.fortios_extender_controller_extender
fortios_facts:
redirect: fortinet.fortios.fortios_facts
fortios_firewall_address:
redirect: fortinet.fortios.fortios_firewall_address
fortios_firewall_address6:
redirect: fortinet.fortios.fortios_firewall_address6
fortios_firewall_address6_template:
redirect: fortinet.fortios.fortios_firewall_address6_template
fortios_firewall_addrgrp:
redirect: fortinet.fortios.fortios_firewall_addrgrp
fortios_firewall_addrgrp6:
redirect: fortinet.fortios.fortios_firewall_addrgrp6
fortios_firewall_auth_portal:
redirect: fortinet.fortios.fortios_firewall_auth_portal
fortios_firewall_central_snat_map:
redirect: fortinet.fortios.fortios_firewall_central_snat_map
fortios_firewall_DoS_policy:
redirect: fortinet.fortios.fortios_firewall_DoS_policy
fortios_firewall_DoS_policy6:
redirect: fortinet.fortios.fortios_firewall_DoS_policy6
fortios_firewall_dnstranslation:
redirect: fortinet.fortios.fortios_firewall_dnstranslation
fortios_firewall_identity_based_route:
redirect: fortinet.fortios.fortios_firewall_identity_based_route
fortios_firewall_interface_policy:
redirect: fortinet.fortios.fortios_firewall_interface_policy
fortios_firewall_interface_policy6:
redirect: fortinet.fortios.fortios_firewall_interface_policy6
fortios_firewall_internet_service:
redirect: fortinet.fortios.fortios_firewall_internet_service
fortios_firewall_internet_service_custom:
redirect: fortinet.fortios.fortios_firewall_internet_service_custom
fortios_firewall_internet_service_group:
redirect: fortinet.fortios.fortios_firewall_internet_service_group
fortios_firewall_ip_translation:
redirect: fortinet.fortios.fortios_firewall_ip_translation
fortios_firewall_ipmacbinding_setting:
redirect: fortinet.fortios.fortios_firewall_ipmacbinding_setting
fortios_firewall_ipmacbinding_table:
redirect: fortinet.fortios.fortios_firewall_ipmacbinding_table
fortios_firewall_ippool:
redirect: fortinet.fortios.fortios_firewall_ippool
fortios_firewall_ippool6:
redirect: fortinet.fortios.fortios_firewall_ippool6
fortios_firewall_ipv6_eh_filter:
redirect: fortinet.fortios.fortios_firewall_ipv6_eh_filter
fortios_firewall_ldb_monitor:
redirect: fortinet.fortios.fortios_firewall_ldb_monitor
fortios_firewall_local_in_policy:
redirect: fortinet.fortios.fortios_firewall_local_in_policy
fortios_firewall_local_in_policy6:
redirect: fortinet.fortios.fortios_firewall_local_in_policy6
fortios_firewall_multicast_address:
redirect: fortinet.fortios.fortios_firewall_multicast_address
fortios_firewall_multicast_address6:
redirect: fortinet.fortios.fortios_firewall_multicast_address6
fortios_firewall_multicast_policy:
redirect: fortinet.fortios.fortios_firewall_multicast_policy
fortios_firewall_multicast_policy6:
redirect: fortinet.fortios.fortios_firewall_multicast_policy6
fortios_firewall_policy:
redirect: fortinet.fortios.fortios_firewall_policy
fortios_firewall_policy46:
redirect: fortinet.fortios.fortios_firewall_policy46
fortios_firewall_policy6:
redirect: fortinet.fortios.fortios_firewall_policy6
fortios_firewall_policy64:
redirect: fortinet.fortios.fortios_firewall_policy64
fortios_firewall_profile_group:
redirect: fortinet.fortios.fortios_firewall_profile_group
fortios_firewall_profile_protocol_options:
redirect: fortinet.fortios.fortios_firewall_profile_protocol_options
fortios_firewall_proxy_address:
redirect: fortinet.fortios.fortios_firewall_proxy_address
fortios_firewall_proxy_addrgrp:
redirect: fortinet.fortios.fortios_firewall_proxy_addrgrp
fortios_firewall_proxy_policy:
redirect: fortinet.fortios.fortios_firewall_proxy_policy
fortios_firewall_schedule_group:
redirect: fortinet.fortios.fortios_firewall_schedule_group
fortios_firewall_schedule_onetime:
redirect: fortinet.fortios.fortios_firewall_schedule_onetime
fortios_firewall_schedule_recurring:
redirect: fortinet.fortios.fortios_firewall_schedule_recurring
fortios_firewall_service_category:
redirect: fortinet.fortios.fortios_firewall_service_category
fortios_firewall_service_custom:
redirect: fortinet.fortios.fortios_firewall_service_custom
fortios_firewall_service_group:
redirect: fortinet.fortios.fortios_firewall_service_group
fortios_firewall_shaper_per_ip_shaper:
redirect: fortinet.fortios.fortios_firewall_shaper_per_ip_shaper
fortios_firewall_shaper_traffic_shaper:
redirect: fortinet.fortios.fortios_firewall_shaper_traffic_shaper
fortios_firewall_shaping_policy:
redirect: fortinet.fortios.fortios_firewall_shaping_policy
fortios_firewall_shaping_profile:
redirect: fortinet.fortios.fortios_firewall_shaping_profile
fortios_firewall_sniffer:
redirect: fortinet.fortios.fortios_firewall_sniffer
fortios_firewall_ssh_host_key:
redirect: fortinet.fortios.fortios_firewall_ssh_host_key
fortios_firewall_ssh_local_ca:
redirect: fortinet.fortios.fortios_firewall_ssh_local_ca
fortios_firewall_ssh_local_key:
redirect: fortinet.fortios.fortios_firewall_ssh_local_key
fortios_firewall_ssh_setting:
redirect: fortinet.fortios.fortios_firewall_ssh_setting
fortios_firewall_ssl_server:
redirect: fortinet.fortios.fortios_firewall_ssl_server
fortios_firewall_ssl_setting:
redirect: fortinet.fortios.fortios_firewall_ssl_setting
fortios_firewall_ssl_ssh_profile:
redirect: fortinet.fortios.fortios_firewall_ssl_ssh_profile
fortios_firewall_ttl_policy:
redirect: fortinet.fortios.fortios_firewall_ttl_policy
fortios_firewall_vip:
redirect: fortinet.fortios.fortios_firewall_vip
fortios_firewall_vip46:
redirect: fortinet.fortios.fortios_firewall_vip46
fortios_firewall_vip6:
redirect: fortinet.fortios.fortios_firewall_vip6
fortios_firewall_vip64:
redirect: fortinet.fortios.fortios_firewall_vip64
fortios_firewall_vipgrp:
redirect: fortinet.fortios.fortios_firewall_vipgrp
fortios_firewall_vipgrp46:
redirect: fortinet.fortios.fortios_firewall_vipgrp46
fortios_firewall_vipgrp6:
redirect: fortinet.fortios.fortios_firewall_vipgrp6
fortios_firewall_vipgrp64:
redirect: fortinet.fortios.fortios_firewall_vipgrp64
fortios_firewall_wildcard_fqdn_custom:
redirect: fortinet.fortios.fortios_firewall_wildcard_fqdn_custom
fortios_firewall_wildcard_fqdn_group:
redirect: fortinet.fortios.fortios_firewall_wildcard_fqdn_group
fortios_ftp_proxy_explicit:
redirect: fortinet.fortios.fortios_ftp_proxy_explicit
fortios_icap_profile:
redirect: fortinet.fortios.fortios_icap_profile
fortios_icap_server:
redirect: fortinet.fortios.fortios_icap_server
fortios_ips_custom:
redirect: fortinet.fortios.fortios_ips_custom
fortios_ips_decoder:
redirect: fortinet.fortios.fortios_ips_decoder
fortios_ips_global:
redirect: fortinet.fortios.fortios_ips_global
fortios_ips_rule:
redirect: fortinet.fortios.fortios_ips_rule
fortios_ips_rule_settings:
redirect: fortinet.fortios.fortios_ips_rule_settings
fortios_ips_sensor:
redirect: fortinet.fortios.fortios_ips_sensor
fortios_ips_settings:
redirect: fortinet.fortios.fortios_ips_settings
fortios_ipv4_policy:
redirect: fortinet.fortios.fortios_ipv4_policy
fortios_log_custom_field:
redirect: fortinet.fortios.fortios_log_custom_field
fortios_log_disk_filter:
redirect: fortinet.fortios.fortios_log_disk_filter
fortios_log_disk_setting:
redirect: fortinet.fortios.fortios_log_disk_setting
fortios_log_eventfilter:
redirect: fortinet.fortios.fortios_log_eventfilter
fortios_log_fortianalyzer2_filter:
redirect: fortinet.fortios.fortios_log_fortianalyzer2_filter
fortios_log_fortianalyzer2_setting:
redirect: fortinet.fortios.fortios_log_fortianalyzer2_setting
fortios_log_fortianalyzer3_filter:
redirect: fortinet.fortios.fortios_log_fortianalyzer3_filter
fortios_log_fortianalyzer3_setting:
redirect: fortinet.fortios.fortios_log_fortianalyzer3_setting
fortios_log_fortianalyzer_filter:
redirect: fortinet.fortios.fortios_log_fortianalyzer_filter
fortios_log_fortianalyzer_override_filter:
redirect: fortinet.fortios.fortios_log_fortianalyzer_override_filter
fortios_log_fortianalyzer_override_setting:
redirect: fortinet.fortios.fortios_log_fortianalyzer_override_setting
fortios_log_fortianalyzer_setting:
redirect: fortinet.fortios.fortios_log_fortianalyzer_setting
fortios_log_fortiguard_filter:
redirect: fortinet.fortios.fortios_log_fortiguard_filter
fortios_log_fortiguard_override_filter:
redirect: fortinet.fortios.fortios_log_fortiguard_override_filter
fortios_log_fortiguard_override_setting:
redirect: fortinet.fortios.fortios_log_fortiguard_override_setting
fortios_log_fortiguard_setting:
redirect: fortinet.fortios.fortios_log_fortiguard_setting
fortios_log_gui_display:
redirect: fortinet.fortios.fortios_log_gui_display
fortios_log_memory_filter:
redirect: fortinet.fortios.fortios_log_memory_filter
fortios_log_memory_global_setting:
redirect: fortinet.fortios.fortios_log_memory_global_setting
fortios_log_memory_setting:
redirect: fortinet.fortios.fortios_log_memory_setting
fortios_log_null_device_filter:
redirect: fortinet.fortios.fortios_log_null_device_filter
fortios_log_null_device_setting:
redirect: fortinet.fortios.fortios_log_null_device_setting
fortios_log_setting:
redirect: fortinet.fortios.fortios_log_setting
fortios_log_syslogd2_filter:
redirect: fortinet.fortios.fortios_log_syslogd2_filter
fortios_log_syslogd2_setting:
redirect: fortinet.fortios.fortios_log_syslogd2_setting
fortios_log_syslogd3_filter:
redirect: fortinet.fortios.fortios_log_syslogd3_filter
fortios_log_syslogd3_setting:
redirect: fortinet.fortios.fortios_log_syslogd3_setting
fortios_log_syslogd4_filter:
redirect: fortinet.fortios.fortios_log_syslogd4_filter
fortios_log_syslogd4_setting:
redirect: fortinet.fortios.fortios_log_syslogd4_setting
fortios_log_syslogd_filter:
redirect: fortinet.fortios.fortios_log_syslogd_filter
fortios_log_syslogd_override_filter:
redirect: fortinet.fortios.fortios_log_syslogd_override_filter
fortios_log_syslogd_override_setting:
redirect: fortinet.fortios.fortios_log_syslogd_override_setting
fortios_log_syslogd_setting:
redirect: fortinet.fortios.fortios_log_syslogd_setting
fortios_log_threat_weight:
redirect: fortinet.fortios.fortios_log_threat_weight
fortios_log_webtrends_filter:
redirect: fortinet.fortios.fortios_log_webtrends_filter
fortios_log_webtrends_setting:
redirect: fortinet.fortios.fortios_log_webtrends_setting
fortios_report_chart:
redirect: fortinet.fortios.fortios_report_chart
fortios_report_dataset:
redirect: fortinet.fortios.fortios_report_dataset
fortios_report_layout:
redirect: fortinet.fortios.fortios_report_layout
fortios_report_setting:
redirect: fortinet.fortios.fortios_report_setting
fortios_report_style:
redirect: fortinet.fortios.fortios_report_style
fortios_report_theme:
redirect: fortinet.fortios.fortios_report_theme
fortios_router_access_list:
redirect: fortinet.fortios.fortios_router_access_list
fortios_router_access_list6:
redirect: fortinet.fortios.fortios_router_access_list6
fortios_router_aspath_list:
redirect: fortinet.fortios.fortios_router_aspath_list
fortios_router_auth_path:
redirect: fortinet.fortios.fortios_router_auth_path
fortios_router_bfd:
redirect: fortinet.fortios.fortios_router_bfd
fortios_router_bfd6:
redirect: fortinet.fortios.fortios_router_bfd6
fortios_router_bgp:
redirect: fortinet.fortios.fortios_router_bgp
fortios_router_community_list:
redirect: fortinet.fortios.fortios_router_community_list
fortios_router_isis:
redirect: fortinet.fortios.fortios_router_isis
fortios_router_key_chain:
redirect: fortinet.fortios.fortios_router_key_chain
fortios_router_multicast:
redirect: fortinet.fortios.fortios_router_multicast
fortios_router_multicast6:
redirect: fortinet.fortios.fortios_router_multicast6
fortios_router_multicast_flow:
redirect: fortinet.fortios.fortios_router_multicast_flow
fortios_router_ospf:
redirect: fortinet.fortios.fortios_router_ospf
fortios_router_ospf6:
redirect: fortinet.fortios.fortios_router_ospf6
fortios_router_policy:
redirect: fortinet.fortios.fortios_router_policy
fortios_router_policy6:
redirect: fortinet.fortios.fortios_router_policy6
fortios_router_prefix_list:
redirect: fortinet.fortios.fortios_router_prefix_list
fortios_router_prefix_list6:
redirect: fortinet.fortios.fortios_router_prefix_list6
fortios_router_rip:
redirect: fortinet.fortios.fortios_router_rip
fortios_router_ripng:
redirect: fortinet.fortios.fortios_router_ripng
fortios_router_route_map:
redirect: fortinet.fortios.fortios_router_route_map
fortios_router_setting:
redirect: fortinet.fortios.fortios_router_setting
fortios_router_static:
redirect: fortinet.fortios.fortios_router_static
fortios_router_static6:
redirect: fortinet.fortios.fortios_router_static6
fortios_spamfilter_bwl:
redirect: fortinet.fortios.fortios_spamfilter_bwl
fortios_spamfilter_bword:
redirect: fortinet.fortios.fortios_spamfilter_bword
fortios_spamfilter_dnsbl:
redirect: fortinet.fortios.fortios_spamfilter_dnsbl
fortios_spamfilter_fortishield:
redirect: fortinet.fortios.fortios_spamfilter_fortishield
fortios_spamfilter_iptrust:
redirect: fortinet.fortios.fortios_spamfilter_iptrust
fortios_spamfilter_mheader:
redirect: fortinet.fortios.fortios_spamfilter_mheader
fortios_spamfilter_options:
redirect: fortinet.fortios.fortios_spamfilter_options
fortios_spamfilter_profile:
redirect: fortinet.fortios.fortios_spamfilter_profile
fortios_ssh_filter_profile:
redirect: fortinet.fortios.fortios_ssh_filter_profile
fortios_switch_controller_802_1X_settings:
redirect: fortinet.fortios.fortios_switch_controller_802_1X_settings
fortios_switch_controller_custom_command:
redirect: fortinet.fortios.fortios_switch_controller_custom_command
fortios_switch_controller_global:
redirect: fortinet.fortios.fortios_switch_controller_global
fortios_switch_controller_igmp_snooping:
redirect: fortinet.fortios.fortios_switch_controller_igmp_snooping
fortios_switch_controller_lldp_profile:
redirect: fortinet.fortios.fortios_switch_controller_lldp_profile
fortios_switch_controller_lldp_settings:
redirect: fortinet.fortios.fortios_switch_controller_lldp_settings
fortios_switch_controller_mac_sync_settings:
redirect: fortinet.fortios.fortios_switch_controller_mac_sync_settings
fortios_switch_controller_managed_switch:
redirect: fortinet.fortios.fortios_switch_controller_managed_switch
fortios_switch_controller_network_monitor_settings:
redirect: fortinet.fortios.fortios_switch_controller_network_monitor_settings
fortios_switch_controller_qos_dot1p_map:
redirect: fortinet.fortios.fortios_switch_controller_qos_dot1p_map
fortios_switch_controller_qos_ip_dscp_map:
redirect: fortinet.fortios.fortios_switch_controller_qos_ip_dscp_map
fortios_switch_controller_qos_qos_policy:
redirect: fortinet.fortios.fortios_switch_controller_qos_qos_policy
fortios_switch_controller_qos_queue_policy:
redirect: fortinet.fortios.fortios_switch_controller_qos_queue_policy
fortios_switch_controller_quarantine:
redirect: fortinet.fortios.fortios_switch_controller_quarantine
fortios_switch_controller_security_policy_802_1X:
redirect: fortinet.fortios.fortios_switch_controller_security_policy_802_1X
fortios_switch_controller_security_policy_captive_portal:
redirect: fortinet.fortios.fortios_switch_controller_security_policy_captive_portal
fortios_switch_controller_sflow:
redirect: fortinet.fortios.fortios_switch_controller_sflow
fortios_switch_controller_storm_control:
redirect: fortinet.fortios.fortios_switch_controller_storm_control
fortios_switch_controller_stp_settings:
redirect: fortinet.fortios.fortios_switch_controller_stp_settings
fortios_switch_controller_switch_group:
redirect: fortinet.fortios.fortios_switch_controller_switch_group
fortios_switch_controller_switch_interface_tag:
redirect: fortinet.fortios.fortios_switch_controller_switch_interface_tag
fortios_switch_controller_switch_log:
redirect: fortinet.fortios.fortios_switch_controller_switch_log
fortios_switch_controller_switch_profile:
redirect: fortinet.fortios.fortios_switch_controller_switch_profile
fortios_switch_controller_system:
redirect: fortinet.fortios.fortios_switch_controller_system
fortios_switch_controller_virtual_port_pool:
redirect: fortinet.fortios.fortios_switch_controller_virtual_port_pool
fortios_switch_controller_vlan:
redirect: fortinet.fortios.fortios_switch_controller_vlan
fortios_system_accprofile:
redirect: fortinet.fortios.fortios_system_accprofile
fortios_system_admin:
redirect: fortinet.fortios.fortios_system_admin
fortios_system_affinity_interrupt:
redirect: fortinet.fortios.fortios_system_affinity_interrupt
fortios_system_affinity_packet_redistribution:
redirect: fortinet.fortios.fortios_system_affinity_packet_redistribution
fortios_system_alarm:
redirect: fortinet.fortios.fortios_system_alarm
fortios_system_alias:
redirect: fortinet.fortios.fortios_system_alias
fortios_system_api_user:
redirect: fortinet.fortios.fortios_system_api_user
fortios_system_arp_table:
redirect: fortinet.fortios.fortios_system_arp_table
fortios_system_auto_install:
redirect: fortinet.fortios.fortios_system_auto_install
fortios_system_auto_script:
redirect: fortinet.fortios.fortios_system_auto_script
fortios_system_automation_action:
redirect: fortinet.fortios.fortios_system_automation_action
fortios_system_automation_destination:
redirect: fortinet.fortios.fortios_system_automation_destination
fortios_system_automation_stitch:
redirect: fortinet.fortios.fortios_system_automation_stitch
fortios_system_automation_trigger:
redirect: fortinet.fortios.fortios_system_automation_trigger
fortios_system_autoupdate_push_update:
redirect: fortinet.fortios.fortios_system_autoupdate_push_update
fortios_system_autoupdate_schedule:
redirect: fortinet.fortios.fortios_system_autoupdate_schedule
fortios_system_autoupdate_tunneling:
redirect: fortinet.fortios.fortios_system_autoupdate_tunneling
fortios_system_central_management:
redirect: fortinet.fortios.fortios_system_central_management
fortios_system_cluster_sync:
redirect: fortinet.fortios.fortios_system_cluster_sync
fortios_system_console:
redirect: fortinet.fortios.fortios_system_console
fortios_system_csf:
redirect: fortinet.fortios.fortios_system_csf
fortios_system_custom_language:
redirect: fortinet.fortios.fortios_system_custom_language
fortios_system_ddns:
redirect: fortinet.fortios.fortios_system_ddns
fortios_system_dedicated_mgmt:
redirect: fortinet.fortios.fortios_system_dedicated_mgmt
fortios_system_dhcp6_server:
redirect: fortinet.fortios.fortios_system_dhcp6_server
fortios_system_dhcp_server:
redirect: fortinet.fortios.fortios_system_dhcp_server
fortios_system_dns:
redirect: fortinet.fortios.fortios_system_dns
fortios_system_dns_database:
redirect: fortinet.fortios.fortios_system_dns_database
fortios_system_dns_server:
redirect: fortinet.fortios.fortios_system_dns_server
fortios_system_dscp_based_priority:
redirect: fortinet.fortios.fortios_system_dscp_based_priority
fortios_system_email_server:
redirect: fortinet.fortios.fortios_system_email_server
fortios_system_external_resource:
redirect: fortinet.fortios.fortios_system_external_resource
fortios_system_fips_cc:
redirect: fortinet.fortios.fortios_system_fips_cc
fortios_system_firmware_upgrade:
redirect: fortinet.fortios.fortios_system_firmware_upgrade
fortios_system_fm:
redirect: fortinet.fortios.fortios_system_fm
fortios_system_fortiguard:
redirect: fortinet.fortios.fortios_system_fortiguard
fortios_system_fortimanager:
redirect: fortinet.fortios.fortios_system_fortimanager
fortios_system_fortisandbox:
redirect: fortinet.fortios.fortios_system_fortisandbox
fortios_system_fsso_polling:
redirect: fortinet.fortios.fortios_system_fsso_polling
fortios_system_ftm_push:
redirect: fortinet.fortios.fortios_system_ftm_push
fortios_system_geoip_override:
redirect: fortinet.fortios.fortios_system_geoip_override
fortios_system_global:
redirect: fortinet.fortios.fortios_system_global
fortios_system_gre_tunnel:
redirect: fortinet.fortios.fortios_system_gre_tunnel
fortios_system_ha:
redirect: fortinet.fortios.fortios_system_ha
fortios_system_ha_monitor:
redirect: fortinet.fortios.fortios_system_ha_monitor
fortios_system_interface:
redirect: fortinet.fortios.fortios_system_interface
fortios_system_ipip_tunnel:
redirect: fortinet.fortios.fortios_system_ipip_tunnel
fortios_system_ips_urlfilter_dns:
redirect: fortinet.fortios.fortios_system_ips_urlfilter_dns
fortios_system_ips_urlfilter_dns6:
redirect: fortinet.fortios.fortios_system_ips_urlfilter_dns6
fortios_system_ipv6_neighbor_cache:
redirect: fortinet.fortios.fortios_system_ipv6_neighbor_cache
fortios_system_ipv6_tunnel:
redirect: fortinet.fortios.fortios_system_ipv6_tunnel
fortios_system_link_monitor:
redirect: fortinet.fortios.fortios_system_link_monitor
fortios_system_mac_address_table:
redirect: fortinet.fortios.fortios_system_mac_address_table
fortios_system_management_tunnel:
redirect: fortinet.fortios.fortios_system_management_tunnel
fortios_system_mobile_tunnel:
redirect: fortinet.fortios.fortios_system_mobile_tunnel
fortios_system_nat64:
redirect: fortinet.fortios.fortios_system_nat64
fortios_system_nd_proxy:
redirect: fortinet.fortios.fortios_system_nd_proxy
fortios_system_netflow:
redirect: fortinet.fortios.fortios_system_netflow
fortios_system_network_visibility:
redirect: fortinet.fortios.fortios_system_network_visibility
fortios_system_ntp:
redirect: fortinet.fortios.fortios_system_ntp
fortios_system_object_tagging:
redirect: fortinet.fortios.fortios_system_object_tagging
fortios_system_password_policy:
redirect: fortinet.fortios.fortios_system_password_policy
fortios_system_password_policy_guest_admin:
redirect: fortinet.fortios.fortios_system_password_policy_guest_admin
fortios_system_pppoe_interface:
redirect: fortinet.fortios.fortios_system_pppoe_interface
fortios_system_probe_response:
redirect: fortinet.fortios.fortios_system_probe_response
fortios_system_proxy_arp:
redirect: fortinet.fortios.fortios_system_proxy_arp
fortios_system_replacemsg_admin:
redirect: fortinet.fortios.fortios_system_replacemsg_admin
fortios_system_replacemsg_alertmail:
redirect: fortinet.fortios.fortios_system_replacemsg_alertmail
fortios_system_replacemsg_auth:
redirect: fortinet.fortios.fortios_system_replacemsg_auth
fortios_system_replacemsg_device_detection_portal:
redirect: fortinet.fortios.fortios_system_replacemsg_device_detection_portal
fortios_system_replacemsg_ec:
redirect: fortinet.fortios.fortios_system_replacemsg_ec
fortios_system_replacemsg_fortiguard_wf:
redirect: fortinet.fortios.fortios_system_replacemsg_fortiguard_wf
fortios_system_replacemsg_ftp:
redirect: fortinet.fortios.fortios_system_replacemsg_ftp
fortios_system_replacemsg_group:
redirect: fortinet.fortios.fortios_system_replacemsg_group
fortios_system_replacemsg_http:
redirect: fortinet.fortios.fortios_system_replacemsg_http
fortios_system_replacemsg_icap:
redirect: fortinet.fortios.fortios_system_replacemsg_icap
fortios_system_replacemsg_image:
redirect: fortinet.fortios.fortios_system_replacemsg_image
fortios_system_replacemsg_mail:
redirect: fortinet.fortios.fortios_system_replacemsg_mail
fortios_system_replacemsg_nac_quar:
redirect: fortinet.fortios.fortios_system_replacemsg_nac_quar
fortios_system_replacemsg_nntp:
redirect: fortinet.fortios.fortios_system_replacemsg_nntp
fortios_system_replacemsg_spam:
redirect: fortinet.fortios.fortios_system_replacemsg_spam
fortios_system_replacemsg_sslvpn:
redirect: fortinet.fortios.fortios_system_replacemsg_sslvpn
fortios_system_replacemsg_traffic_quota:
redirect: fortinet.fortios.fortios_system_replacemsg_traffic_quota
fortios_system_replacemsg_utm:
redirect: fortinet.fortios.fortios_system_replacemsg_utm
fortios_system_replacemsg_webproxy:
redirect: fortinet.fortios.fortios_system_replacemsg_webproxy
fortios_system_resource_limits:
redirect: fortinet.fortios.fortios_system_resource_limits
fortios_system_sdn_connector:
redirect: fortinet.fortios.fortios_system_sdn_connector
fortios_system_session_helper:
redirect: fortinet.fortios.fortios_system_session_helper
fortios_system_session_ttl:
redirect: fortinet.fortios.fortios_system_session_ttl
fortios_system_settings:
redirect: fortinet.fortios.fortios_system_settings
fortios_system_sflow:
redirect: fortinet.fortios.fortios_system_sflow
fortios_system_sit_tunnel:
redirect: fortinet.fortios.fortios_system_sit_tunnel
fortios_system_sms_server:
redirect: fortinet.fortios.fortios_system_sms_server
fortios_system_snmp_community:
redirect: fortinet.fortios.fortios_system_snmp_community
fortios_system_snmp_sysinfo:
redirect: fortinet.fortios.fortios_system_snmp_sysinfo
fortios_system_snmp_user:
redirect: fortinet.fortios.fortios_system_snmp_user
fortios_system_storage:
redirect: fortinet.fortios.fortios_system_storage
fortios_system_switch_interface:
redirect: fortinet.fortios.fortios_system_switch_interface
fortios_system_tos_based_priority:
redirect: fortinet.fortios.fortios_system_tos_based_priority
fortios_system_vdom:
redirect: fortinet.fortios.fortios_system_vdom
fortios_system_vdom_dns:
redirect: fortinet.fortios.fortios_system_vdom_dns
fortios_system_vdom_exception:
redirect: fortinet.fortios.fortios_system_vdom_exception
fortios_system_vdom_link:
redirect: fortinet.fortios.fortios_system_vdom_link
fortios_system_vdom_netflow:
redirect: fortinet.fortios.fortios_system_vdom_netflow
fortios_system_vdom_property:
redirect: fortinet.fortios.fortios_system_vdom_property
fortios_system_vdom_radius_server:
redirect: fortinet.fortios.fortios_system_vdom_radius_server
fortios_system_vdom_sflow:
redirect: fortinet.fortios.fortios_system_vdom_sflow
fortios_system_virtual_wan_link:
redirect: fortinet.fortios.fortios_system_virtual_wan_link
fortios_system_virtual_wire_pair:
redirect: fortinet.fortios.fortios_system_virtual_wire_pair
fortios_system_vxlan:
redirect: fortinet.fortios.fortios_system_vxlan
fortios_system_wccp:
redirect: fortinet.fortios.fortios_system_wccp
fortios_system_zone:
redirect: fortinet.fortios.fortios_system_zone
fortios_user_adgrp:
redirect: fortinet.fortios.fortios_user_adgrp
fortios_user_device:
redirect: fortinet.fortios.fortios_user_device
fortios_user_device_access_list:
redirect: fortinet.fortios.fortios_user_device_access_list
fortios_user_device_category:
redirect: fortinet.fortios.fortios_user_device_category
fortios_user_device_group:
redirect: fortinet.fortios.fortios_user_device_group
fortios_user_domain_controller:
redirect: fortinet.fortios.fortios_user_domain_controller
fortios_user_fortitoken:
redirect: fortinet.fortios.fortios_user_fortitoken
fortios_user_fsso:
redirect: fortinet.fortios.fortios_user_fsso
fortios_user_fsso_polling:
redirect: fortinet.fortios.fortios_user_fsso_polling
fortios_user_group:
redirect: fortinet.fortios.fortios_user_group
fortios_user_krb_keytab:
redirect: fortinet.fortios.fortios_user_krb_keytab
fortios_user_ldap:
redirect: fortinet.fortios.fortios_user_ldap
fortios_user_local:
redirect: fortinet.fortios.fortios_user_local
fortios_user_password_policy:
redirect: fortinet.fortios.fortios_user_password_policy
fortios_user_peer:
redirect: fortinet.fortios.fortios_user_peer
fortios_user_peergrp:
redirect: fortinet.fortios.fortios_user_peergrp
fortios_user_pop3:
redirect: fortinet.fortios.fortios_user_pop3
fortios_user_quarantine:
redirect: fortinet.fortios.fortios_user_quarantine
fortios_user_radius:
redirect: fortinet.fortios.fortios_user_radius
fortios_user_security_exempt_list:
redirect: fortinet.fortios.fortios_user_security_exempt_list
fortios_user_setting:
redirect: fortinet.fortios.fortios_user_setting
fortios_user_tacacsplus:
redirect: fortinet.fortios.fortios_user_tacacsplus
fortios_voip_profile:
redirect: fortinet.fortios.fortios_voip_profile
fortios_vpn_certificate_ca:
redirect: fortinet.fortios.fortios_vpn_certificate_ca
fortios_vpn_certificate_crl:
redirect: fortinet.fortios.fortios_vpn_certificate_crl
fortios_vpn_certificate_local:
redirect: fortinet.fortios.fortios_vpn_certificate_local
fortios_vpn_certificate_ocsp_server:
redirect: fortinet.fortios.fortios_vpn_certificate_ocsp_server
fortios_vpn_certificate_remote:
redirect: fortinet.fortios.fortios_vpn_certificate_remote
fortios_vpn_certificate_setting:
redirect: fortinet.fortios.fortios_vpn_certificate_setting
fortios_vpn_ipsec_concentrator:
redirect: fortinet.fortios.fortios_vpn_ipsec_concentrator
fortios_vpn_ipsec_forticlient:
redirect: fortinet.fortios.fortios_vpn_ipsec_forticlient
fortios_vpn_ipsec_manualkey:
redirect: fortinet.fortios.fortios_vpn_ipsec_manualkey
fortios_vpn_ipsec_manualkey_interface:
redirect: fortinet.fortios.fortios_vpn_ipsec_manualkey_interface
fortios_vpn_ipsec_phase1:
redirect: fortinet.fortios.fortios_vpn_ipsec_phase1
fortios_vpn_ipsec_phase1_interface:
redirect: fortinet.fortios.fortios_vpn_ipsec_phase1_interface
fortios_vpn_ipsec_phase2:
redirect: fortinet.fortios.fortios_vpn_ipsec_phase2
fortios_vpn_ipsec_phase2_interface:
redirect: fortinet.fortios.fortios_vpn_ipsec_phase2_interface
fortios_vpn_l2tp:
redirect: fortinet.fortios.fortios_vpn_l2tp
fortios_vpn_pptp:
redirect: fortinet.fortios.fortios_vpn_pptp
fortios_vpn_ssl_settings:
redirect: fortinet.fortios.fortios_vpn_ssl_settings
fortios_vpn_ssl_web_host_check_software:
redirect: fortinet.fortios.fortios_vpn_ssl_web_host_check_software
fortios_vpn_ssl_web_portal:
redirect: fortinet.fortios.fortios_vpn_ssl_web_portal
fortios_vpn_ssl_web_realm:
redirect: fortinet.fortios.fortios_vpn_ssl_web_realm
fortios_vpn_ssl_web_user_bookmark:
redirect: fortinet.fortios.fortios_vpn_ssl_web_user_bookmark
fortios_vpn_ssl_web_user_group_bookmark:
redirect: fortinet.fortios.fortios_vpn_ssl_web_user_group_bookmark
fortios_waf_main_class:
redirect: fortinet.fortios.fortios_waf_main_class
fortios_waf_profile:
redirect: fortinet.fortios.fortios_waf_profile
fortios_waf_signature:
redirect: fortinet.fortios.fortios_waf_signature
fortios_waf_sub_class:
redirect: fortinet.fortios.fortios_waf_sub_class
fortios_wanopt_auth_group:
redirect: fortinet.fortios.fortios_wanopt_auth_group
fortios_wanopt_cache_service:
redirect: fortinet.fortios.fortios_wanopt_cache_service
fortios_wanopt_content_delivery_network_rule:
redirect: fortinet.fortios.fortios_wanopt_content_delivery_network_rule
fortios_wanopt_peer:
redirect: fortinet.fortios.fortios_wanopt_peer
fortios_wanopt_profile:
redirect: fortinet.fortios.fortios_wanopt_profile
fortios_wanopt_remote_storage:
redirect: fortinet.fortios.fortios_wanopt_remote_storage
fortios_wanopt_settings:
redirect: fortinet.fortios.fortios_wanopt_settings
fortios_wanopt_webcache:
redirect: fortinet.fortios.fortios_wanopt_webcache
fortios_web_proxy_debug_url:
redirect: fortinet.fortios.fortios_web_proxy_debug_url
fortios_web_proxy_explicit:
redirect: fortinet.fortios.fortios_web_proxy_explicit
fortios_web_proxy_forward_server:
redirect: fortinet.fortios.fortios_web_proxy_forward_server
fortios_web_proxy_forward_server_group:
redirect: fortinet.fortios.fortios_web_proxy_forward_server_group
fortios_web_proxy_global:
redirect: fortinet.fortios.fortios_web_proxy_global
fortios_web_proxy_profile:
redirect: fortinet.fortios.fortios_web_proxy_profile
fortios_web_proxy_url_match:
redirect: fortinet.fortios.fortios_web_proxy_url_match
fortios_web_proxy_wisp:
redirect: fortinet.fortios.fortios_web_proxy_wisp
fortios_webfilter:
redirect: fortinet.fortios.fortios_webfilter
fortios_webfilter_content:
redirect: fortinet.fortios.fortios_webfilter_content
fortios_webfilter_content_header:
redirect: fortinet.fortios.fortios_webfilter_content_header
fortios_webfilter_fortiguard:
redirect: fortinet.fortios.fortios_webfilter_fortiguard
fortios_webfilter_ftgd_local_cat:
redirect: fortinet.fortios.fortios_webfilter_ftgd_local_cat
fortios_webfilter_ftgd_local_rating:
redirect: fortinet.fortios.fortios_webfilter_ftgd_local_rating
fortios_webfilter_ips_urlfilter_cache_setting:
redirect: fortinet.fortios.fortios_webfilter_ips_urlfilter_cache_setting
fortios_webfilter_ips_urlfilter_setting:
redirect: fortinet.fortios.fortios_webfilter_ips_urlfilter_setting
fortios_webfilter_ips_urlfilter_setting6:
redirect: fortinet.fortios.fortios_webfilter_ips_urlfilter_setting6
fortios_webfilter_override:
redirect: fortinet.fortios.fortios_webfilter_override
fortios_webfilter_profile:
redirect: fortinet.fortios.fortios_webfilter_profile
fortios_webfilter_search_engine:
redirect: fortinet.fortios.fortios_webfilter_search_engine
fortios_webfilter_urlfilter:
redirect: fortinet.fortios.fortios_webfilter_urlfilter
fortios_wireless_controller_ap_status:
redirect: fortinet.fortios.fortios_wireless_controller_ap_status
fortios_wireless_controller_ble_profile:
redirect: fortinet.fortios.fortios_wireless_controller_ble_profile
fortios_wireless_controller_bonjour_profile:
redirect: fortinet.fortios.fortios_wireless_controller_bonjour_profile
fortios_wireless_controller_global:
redirect: fortinet.fortios.fortios_wireless_controller_global
fortios_wireless_controller_hotspot20_anqp_3gpp_cellular:
redirect: fortinet.fortios.fortios_wireless_controller_hotspot20_anqp_3gpp_cellular
fortios_wireless_controller_hotspot20_anqp_ip_address_type:
redirect: fortinet.fortios.fortios_wireless_controller_hotspot20_anqp_ip_address_type
fortios_wireless_controller_hotspot20_anqp_nai_realm:
redirect: fortinet.fortios.fortios_wireless_controller_hotspot20_anqp_nai_realm
fortios_wireless_controller_hotspot20_anqp_network_auth_type:
redirect: fortinet.fortios.fortios_wireless_controller_hotspot20_anqp_network_auth_type
fortios_wireless_controller_hotspot20_anqp_roaming_consortium:
redirect: fortinet.fortios.fortios_wireless_controller_hotspot20_anqp_roaming_consortium
fortios_wireless_controller_hotspot20_anqp_venue_name:
redirect: fortinet.fortios.fortios_wireless_controller_hotspot20_anqp_venue_name
fortios_wireless_controller_hotspot20_h2qp_conn_capability:
redirect: fortinet.fortios.fortios_wireless_controller_hotspot20_h2qp_conn_capability
fortios_wireless_controller_hotspot20_h2qp_operator_name:
redirect: fortinet.fortios.fortios_wireless_controller_hotspot20_h2qp_operator_name
fortios_wireless_controller_hotspot20_h2qp_osu_provider:
redirect: fortinet.fortios.fortios_wireless_controller_hotspot20_h2qp_osu_provider
fortios_wireless_controller_hotspot20_h2qp_wan_metric:
redirect: fortinet.fortios.fortios_wireless_controller_hotspot20_h2qp_wan_metric
fortios_wireless_controller_hotspot20_hs_profile:
redirect: fortinet.fortios.fortios_wireless_controller_hotspot20_hs_profile
fortios_wireless_controller_hotspot20_icon:
redirect: fortinet.fortios.fortios_wireless_controller_hotspot20_icon
fortios_wireless_controller_hotspot20_qos_map:
redirect: fortinet.fortios.fortios_wireless_controller_hotspot20_qos_map
fortios_wireless_controller_inter_controller:
redirect: fortinet.fortios.fortios_wireless_controller_inter_controller
fortios_wireless_controller_qos_profile:
redirect: fortinet.fortios.fortios_wireless_controller_qos_profile
fortios_wireless_controller_setting:
redirect: fortinet.fortios.fortios_wireless_controller_setting
fortios_wireless_controller_timers:
redirect: fortinet.fortios.fortios_wireless_controller_timers
fortios_wireless_controller_utm_profile:
redirect: fortinet.fortios.fortios_wireless_controller_utm_profile
fortios_wireless_controller_vap:
redirect: fortinet.fortios.fortios_wireless_controller_vap
fortios_wireless_controller_vap_group:
redirect: fortinet.fortios.fortios_wireless_controller_vap_group
fortios_wireless_controller_wids_profile:
redirect: fortinet.fortios.fortios_wireless_controller_wids_profile
fortios_wireless_controller_wtp:
redirect: fortinet.fortios.fortios_wireless_controller_wtp
fortios_wireless_controller_wtp_group:
redirect: fortinet.fortios.fortios_wireless_controller_wtp_group
fortios_wireless_controller_wtp_profile:
redirect: fortinet.fortios.fortios_wireless_controller_wtp_profile
netbox_device:
redirect: netbox.netbox.netbox_device
netbox_ip_address:
redirect: netbox.netbox.netbox_ip_address
netbox_interface:
redirect: netbox.netbox.netbox_interface
netbox_prefix:
redirect: netbox.netbox.netbox_prefix
netbox_site:
redirect: netbox.netbox.netbox_site
aws_netapp_cvs_FileSystems:
redirect: netapp.aws.aws_netapp_cvs_filesystems
aws_netapp_cvs_active_directory:
redirect: netapp.aws.aws_netapp_cvs_active_directory
aws_netapp_cvs_pool:
redirect: netapp.aws.aws_netapp_cvs_pool
aws_netapp_cvs_snapshots:
redirect: netapp.aws.aws_netapp_cvs_snapshots
na_elementsw_access_group:
redirect: netapp.elementsw.na_elementsw_access_group
na_elementsw_account:
redirect: netapp.elementsw.na_elementsw_account
na_elementsw_admin_users:
redirect: netapp.elementsw.na_elementsw_admin_users
na_elementsw_backup:
redirect: netapp.elementsw.na_elementsw_backup
na_elementsw_check_connections:
redirect: netapp.elementsw.na_elementsw_check_connections
na_elementsw_cluster:
redirect: netapp.elementsw.na_elementsw_cluster
na_elementsw_cluster_config:
redirect: netapp.elementsw.na_elementsw_cluster_config
na_elementsw_cluster_pair:
redirect: netapp.elementsw.na_elementsw_cluster_pair
na_elementsw_cluster_snmp:
redirect: netapp.elementsw.na_elementsw_cluster_snmp
na_elementsw_drive:
redirect: netapp.elementsw.na_elementsw_drive
na_elementsw_initiators:
redirect: netapp.elementsw.na_elementsw_initiators
na_elementsw_ldap:
redirect: netapp.elementsw.na_elementsw_ldap
na_elementsw_network_interfaces:
redirect: netapp.elementsw.na_elementsw_network_interfaces
na_elementsw_node:
redirect: netapp.elementsw.na_elementsw_node
na_elementsw_snapshot:
redirect: netapp.elementsw.na_elementsw_snapshot
na_elementsw_snapshot_restore:
redirect: netapp.elementsw.na_elementsw_snapshot_restore
na_elementsw_snapshot_schedule:
redirect: netapp.elementsw.na_elementsw_snapshot_schedule
na_elementsw_vlan:
redirect: netapp.elementsw.na_elementsw_vlan
na_elementsw_volume:
redirect: netapp.elementsw.na_elementsw_volume
na_elementsw_volume_clone:
redirect: netapp.elementsw.na_elementsw_volume_clone
na_elementsw_volume_pair:
redirect: netapp.elementsw.na_elementsw_volume_pair
na_ontap_aggregate:
redirect: netapp.ontap.na_ontap_aggregate
na_ontap_autosupport:
redirect: netapp.ontap.na_ontap_autosupport
na_ontap_broadcast_domain:
redirect: netapp.ontap.na_ontap_broadcast_domain
na_ontap_broadcast_domain_ports:
redirect: netapp.ontap.na_ontap_broadcast_domain_ports
na_ontap_cg_snapshot:
redirect: netapp.ontap.na_ontap_cg_snapshot
na_ontap_cifs:
redirect: netapp.ontap.na_ontap_cifs
na_ontap_cifs_acl:
redirect: netapp.ontap.na_ontap_cifs_acl
na_ontap_cifs_server:
redirect: netapp.ontap.na_ontap_cifs_server
na_ontap_cluster:
redirect: netapp.ontap.na_ontap_cluster
na_ontap_cluster_ha:
redirect: netapp.ontap.na_ontap_cluster_ha
na_ontap_cluster_peer:
redirect: netapp.ontap.na_ontap_cluster_peer
na_ontap_command:
redirect: netapp.ontap.na_ontap_command
na_ontap_disks:
redirect: netapp.ontap.na_ontap_disks
na_ontap_dns:
redirect: netapp.ontap.na_ontap_dns
na_ontap_export_policy:
redirect: netapp.ontap.na_ontap_export_policy
na_ontap_export_policy_rule:
redirect: netapp.ontap.na_ontap_export_policy_rule
na_ontap_fcp:
redirect: netapp.ontap.na_ontap_fcp
na_ontap_firewall_policy:
redirect: netapp.ontap.na_ontap_firewall_policy
na_ontap_firmware_upgrade:
redirect: netapp.ontap.na_ontap_firmware_upgrade
na_ontap_flexcache:
redirect: netapp.ontap.na_ontap_flexcache
na_ontap_igroup:
redirect: netapp.ontap.na_ontap_igroup
na_ontap_igroup_initiator:
redirect: netapp.ontap.na_ontap_igroup_initiator
na_ontap_info:
redirect: netapp.ontap.na_ontap_info
na_ontap_interface:
redirect: netapp.ontap.na_ontap_interface
na_ontap_ipspace:
redirect: netapp.ontap.na_ontap_ipspace
na_ontap_iscsi:
redirect: netapp.ontap.na_ontap_iscsi
na_ontap_job_schedule:
redirect: netapp.ontap.na_ontap_job_schedule
na_ontap_kerberos_realm:
redirect: netapp.ontap.na_ontap_kerberos_realm
na_ontap_ldap:
redirect: netapp.ontap.na_ontap_ldap
na_ontap_ldap_client:
redirect: netapp.ontap.na_ontap_ldap_client
na_ontap_license:
redirect: netapp.ontap.na_ontap_license
na_ontap_lun:
redirect: netapp.ontap.na_ontap_lun
na_ontap_lun_copy:
redirect: netapp.ontap.na_ontap_lun_copy
na_ontap_lun_map:
redirect: netapp.ontap.na_ontap_lun_map
na_ontap_motd:
redirect: netapp.ontap.na_ontap_motd
na_ontap_ndmp:
redirect: netapp.ontap.na_ontap_ndmp
na_ontap_net_ifgrp:
redirect: netapp.ontap.na_ontap_net_ifgrp
na_ontap_net_port:
redirect: netapp.ontap.na_ontap_net_port
na_ontap_net_routes:
redirect: netapp.ontap.na_ontap_net_routes
na_ontap_net_subnet:
redirect: netapp.ontap.na_ontap_net_subnet
na_ontap_net_vlan:
redirect: netapp.ontap.na_ontap_net_vlan
na_ontap_nfs:
redirect: netapp.ontap.na_ontap_nfs
na_ontap_node:
redirect: netapp.ontap.na_ontap_node
na_ontap_ntp:
redirect: netapp.ontap.na_ontap_ntp
na_ontap_nvme:
redirect: netapp.ontap.na_ontap_nvme
na_ontap_nvme_namespace:
redirect: netapp.ontap.na_ontap_nvme_namespace
na_ontap_nvme_subsystem:
redirect: netapp.ontap.na_ontap_nvme_subsystem
na_ontap_object_store:
redirect: netapp.ontap.na_ontap_object_store
na_ontap_ports:
redirect: netapp.ontap.na_ontap_ports
na_ontap_portset:
redirect: netapp.ontap.na_ontap_portset
na_ontap_qos_adaptive_policy_group:
redirect: netapp.ontap.na_ontap_qos_adaptive_policy_group
na_ontap_qos_policy_group:
redirect: netapp.ontap.na_ontap_qos_policy_group
na_ontap_qtree:
redirect: netapp.ontap.na_ontap_qtree
na_ontap_quotas:
redirect: netapp.ontap.na_ontap_quotas
na_ontap_security_key_manager:
redirect: netapp.ontap.na_ontap_security_key_manager
na_ontap_service_processor_network:
redirect: netapp.ontap.na_ontap_service_processor_network
na_ontap_snapmirror:
redirect: netapp.ontap.na_ontap_snapmirror
na_ontap_snapshot:
redirect: netapp.ontap.na_ontap_snapshot
na_ontap_snapshot_policy:
redirect: netapp.ontap.na_ontap_snapshot_policy
na_ontap_snmp:
redirect: netapp.ontap.na_ontap_snmp
na_ontap_software_update:
redirect: netapp.ontap.na_ontap_software_update
na_ontap_svm:
redirect: netapp.ontap.na_ontap_svm
na_ontap_svm_options:
redirect: netapp.ontap.na_ontap_svm_options
na_ontap_ucadapter:
redirect: netapp.ontap.na_ontap_ucadapter
na_ontap_unix_group:
redirect: netapp.ontap.na_ontap_unix_group
na_ontap_unix_user:
redirect: netapp.ontap.na_ontap_unix_user
na_ontap_user:
redirect: netapp.ontap.na_ontap_user
na_ontap_user_role:
redirect: netapp.ontap.na_ontap_user_role
na_ontap_volume:
redirect: netapp.ontap.na_ontap_volume
na_ontap_volume_autosize:
redirect: netapp.ontap.na_ontap_volume_autosize
na_ontap_volume_clone:
redirect: netapp.ontap.na_ontap_volume_clone
na_ontap_vscan:
redirect: netapp.ontap.na_ontap_vscan
na_ontap_vscan_on_access_policy:
redirect: netapp.ontap.na_ontap_vscan_on_access_policy
na_ontap_vscan_on_demand_task:
redirect: netapp.ontap.na_ontap_vscan_on_demand_task
na_ontap_vscan_scanner_pool:
redirect: netapp.ontap.na_ontap_vscan_scanner_pool
na_ontap_vserver_cifs_security:
redirect: netapp.ontap.na_ontap_vserver_cifs_security
na_ontap_vserver_peer:
redirect: netapp.ontap.na_ontap_vserver_peer
cp_mgmt_access_layer:
redirect: check_point.mgmt.cp_mgmt_access_layer
cp_mgmt_access_layer_facts:
redirect: check_point.mgmt.cp_mgmt_access_layer_facts
cp_mgmt_access_role:
redirect: check_point.mgmt.cp_mgmt_access_role
cp_mgmt_access_role_facts:
redirect: check_point.mgmt.cp_mgmt_access_role_facts
cp_mgmt_access_rule:
redirect: check_point.mgmt.cp_mgmt_access_rule
cp_mgmt_access_rule_facts:
redirect: check_point.mgmt.cp_mgmt_access_rule_facts
cp_mgmt_address_range:
redirect: check_point.mgmt.cp_mgmt_address_range
cp_mgmt_address_range_facts:
redirect: check_point.mgmt.cp_mgmt_address_range_facts
cp_mgmt_administrator:
redirect: check_point.mgmt.cp_mgmt_administrator
cp_mgmt_administrator_facts:
redirect: check_point.mgmt.cp_mgmt_administrator_facts
cp_mgmt_application_site:
redirect: check_point.mgmt.cp_mgmt_application_site
cp_mgmt_application_site_category:
redirect: check_point.mgmt.cp_mgmt_application_site_category
cp_mgmt_application_site_category_facts:
redirect: check_point.mgmt.cp_mgmt_application_site_category_facts
cp_mgmt_application_site_facts:
redirect: check_point.mgmt.cp_mgmt_application_site_facts
cp_mgmt_application_site_group:
redirect: check_point.mgmt.cp_mgmt_application_site_group
cp_mgmt_application_site_group_facts:
redirect: check_point.mgmt.cp_mgmt_application_site_group_facts
cp_mgmt_assign_global_assignment:
redirect: check_point.mgmt.cp_mgmt_assign_global_assignment
cp_mgmt_discard:
redirect: check_point.mgmt.cp_mgmt_discard
cp_mgmt_dns_domain:
redirect: check_point.mgmt.cp_mgmt_dns_domain
cp_mgmt_dns_domain_facts:
redirect: check_point.mgmt.cp_mgmt_dns_domain_facts
cp_mgmt_dynamic_object:
redirect: check_point.mgmt.cp_mgmt_dynamic_object
cp_mgmt_dynamic_object_facts:
redirect: check_point.mgmt.cp_mgmt_dynamic_object_facts
cp_mgmt_exception_group:
redirect: check_point.mgmt.cp_mgmt_exception_group
cp_mgmt_exception_group_facts:
redirect: check_point.mgmt.cp_mgmt_exception_group_facts
cp_mgmt_global_assignment:
redirect: check_point.mgmt.cp_mgmt_global_assignment
cp_mgmt_global_assignment_facts:
redirect: check_point.mgmt.cp_mgmt_global_assignment_facts
cp_mgmt_group:
redirect: check_point.mgmt.cp_mgmt_group
cp_mgmt_group_facts:
redirect: check_point.mgmt.cp_mgmt_group_facts
cp_mgmt_group_with_exclusion:
redirect: check_point.mgmt.cp_mgmt_group_with_exclusion
cp_mgmt_group_with_exclusion_facts:
redirect: check_point.mgmt.cp_mgmt_group_with_exclusion_facts
cp_mgmt_host:
redirect: check_point.mgmt.cp_mgmt_host
cp_mgmt_host_facts:
redirect: check_point.mgmt.cp_mgmt_host_facts
cp_mgmt_install_policy:
redirect: check_point.mgmt.cp_mgmt_install_policy
cp_mgmt_mds_facts:
redirect: check_point.mgmt.cp_mgmt_mds_facts
cp_mgmt_multicast_address_range:
redirect: check_point.mgmt.cp_mgmt_multicast_address_range
cp_mgmt_multicast_address_range_facts:
redirect: check_point.mgmt.cp_mgmt_multicast_address_range_facts
cp_mgmt_network:
redirect: check_point.mgmt.cp_mgmt_network
cp_mgmt_network_facts:
redirect: check_point.mgmt.cp_mgmt_network_facts
cp_mgmt_package:
redirect: check_point.mgmt.cp_mgmt_package
cp_mgmt_package_facts:
redirect: check_point.mgmt.cp_mgmt_package_facts
cp_mgmt_publish:
redirect: check_point.mgmt.cp_mgmt_publish
cp_mgmt_put_file:
redirect: check_point.mgmt.cp_mgmt_put_file
cp_mgmt_run_ips_update:
redirect: check_point.mgmt.cp_mgmt_run_ips_update
cp_mgmt_run_script:
redirect: check_point.mgmt.cp_mgmt_run_script
cp_mgmt_security_zone:
redirect: check_point.mgmt.cp_mgmt_security_zone
cp_mgmt_security_zone_facts:
redirect: check_point.mgmt.cp_mgmt_security_zone_facts
cp_mgmt_service_dce_rpc:
redirect: check_point.mgmt.cp_mgmt_service_dce_rpc
cp_mgmt_service_dce_rpc_facts:
redirect: check_point.mgmt.cp_mgmt_service_dce_rpc_facts
cp_mgmt_service_group:
redirect: check_point.mgmt.cp_mgmt_service_group
cp_mgmt_service_group_facts:
redirect: check_point.mgmt.cp_mgmt_service_group_facts
cp_mgmt_service_icmp:
redirect: check_point.mgmt.cp_mgmt_service_icmp
cp_mgmt_service_icmp6:
redirect: check_point.mgmt.cp_mgmt_service_icmp6
cp_mgmt_service_icmp6_facts:
redirect: check_point.mgmt.cp_mgmt_service_icmp6_facts
cp_mgmt_service_icmp_facts:
redirect: check_point.mgmt.cp_mgmt_service_icmp_facts
cp_mgmt_service_other:
redirect: check_point.mgmt.cp_mgmt_service_other
cp_mgmt_service_other_facts:
redirect: check_point.mgmt.cp_mgmt_service_other_facts
cp_mgmt_service_rpc:
redirect: check_point.mgmt.cp_mgmt_service_rpc
cp_mgmt_service_rpc_facts:
redirect: check_point.mgmt.cp_mgmt_service_rpc_facts
cp_mgmt_service_sctp:
redirect: check_point.mgmt.cp_mgmt_service_sctp
cp_mgmt_service_sctp_facts:
redirect: check_point.mgmt.cp_mgmt_service_sctp_facts
cp_mgmt_service_tcp:
redirect: check_point.mgmt.cp_mgmt_service_tcp
cp_mgmt_service_tcp_facts:
redirect: check_point.mgmt.cp_mgmt_service_tcp_facts
cp_mgmt_service_udp:
redirect: check_point.mgmt.cp_mgmt_service_udp
cp_mgmt_service_udp_facts:
redirect: check_point.mgmt.cp_mgmt_service_udp_facts
cp_mgmt_session_facts:
redirect: check_point.mgmt.cp_mgmt_session_facts
cp_mgmt_simple_gateway:
redirect: check_point.mgmt.cp_mgmt_simple_gateway
cp_mgmt_simple_gateway_facts:
redirect: check_point.mgmt.cp_mgmt_simple_gateway_facts
cp_mgmt_tag:
redirect: check_point.mgmt.cp_mgmt_tag
cp_mgmt_tag_facts:
redirect: check_point.mgmt.cp_mgmt_tag_facts
cp_mgmt_threat_exception:
redirect: check_point.mgmt.cp_mgmt_threat_exception
cp_mgmt_threat_exception_facts:
redirect: check_point.mgmt.cp_mgmt_threat_exception_facts
cp_mgmt_threat_indicator:
redirect: check_point.mgmt.cp_mgmt_threat_indicator
cp_mgmt_threat_indicator_facts:
redirect: check_point.mgmt.cp_mgmt_threat_indicator_facts
cp_mgmt_threat_layer:
redirect: check_point.mgmt.cp_mgmt_threat_layer
cp_mgmt_threat_layer_facts:
redirect: check_point.mgmt.cp_mgmt_threat_layer_facts
cp_mgmt_threat_profile:
redirect: check_point.mgmt.cp_mgmt_threat_profile
cp_mgmt_threat_profile_facts:
redirect: check_point.mgmt.cp_mgmt_threat_profile_facts
cp_mgmt_threat_protection_override:
redirect: check_point.mgmt.cp_mgmt_threat_protection_override
cp_mgmt_threat_rule:
redirect: check_point.mgmt.cp_mgmt_threat_rule
cp_mgmt_threat_rule_facts:
redirect: check_point.mgmt.cp_mgmt_threat_rule_facts
cp_mgmt_time:
redirect: check_point.mgmt.cp_mgmt_time
cp_mgmt_time_facts:
redirect: check_point.mgmt.cp_mgmt_time_facts
cp_mgmt_verify_policy:
redirect: check_point.mgmt.cp_mgmt_verify_policy
cp_mgmt_vpn_community_meshed:
redirect: check_point.mgmt.cp_mgmt_vpn_community_meshed
cp_mgmt_vpn_community_meshed_facts:
redirect: check_point.mgmt.cp_mgmt_vpn_community_meshed_facts
cp_mgmt_vpn_community_star:
redirect: check_point.mgmt.cp_mgmt_vpn_community_star
cp_mgmt_vpn_community_star_facts:
redirect: check_point.mgmt.cp_mgmt_vpn_community_star_facts
cp_mgmt_wildcard:
redirect: check_point.mgmt.cp_mgmt_wildcard
cp_mgmt_wildcard_facts:
redirect: check_point.mgmt.cp_mgmt_wildcard_facts
eos_ospfv2:
redirect: arista.eos.eos_ospfv2
eos_static_route:
redirect: arista.eos.eos_static_route
eos_acls:
redirect: arista.eos.eos_acls
eos_interfaces:
redirect: arista.eos.eos_interfaces
eos_facts:
redirect: arista.eos.eos_facts
eos_logging:
redirect: arista.eos.eos_logging
eos_lag_interfaces:
redirect: arista.eos.eos_lag_interfaces
eos_l2_interfaces:
redirect: arista.eos.eos_l2_interfaces
eos_l3_interface:
redirect: arista.eos.eos_l3_interface
eos_lacp:
redirect: arista.eos.eos_lacp
eos_lldp_global:
redirect: arista.eos.eos_lldp_global
eos_static_routes:
redirect: arista.eos.eos_static_routes
eos_lacp_interfaces:
redirect: arista.eos.eos_lacp_interfaces
eos_system:
redirect: arista.eos.eos_system
eos_vlan:
redirect: arista.eos.eos_vlan
eos_eapi:
redirect: arista.eos.eos_eapi
eos_acl_interfaces:
redirect: arista.eos.eos_acl_interfaces
eos_l2_interface:
redirect: arista.eos.eos_l2_interface
eos_lldp_interfaces:
redirect: arista.eos.eos_lldp_interfaces
eos_command:
redirect: arista.eos.eos_command
eos_linkagg:
redirect: arista.eos.eos_linkagg
eos_l3_interfaces:
redirect: arista.eos.eos_l3_interfaces
eos_vlans:
redirect: arista.eos.eos_vlans
eos_user:
redirect: arista.eos.eos_user
eos_banner:
redirect: arista.eos.eos_banner
eos_lldp:
redirect: arista.eos.eos_lldp
eos_interface:
redirect: arista.eos.eos_interface
eos_config:
redirect: arista.eos.eos_config
eos_bgp:
redirect: arista.eos.eos_bgp
eos_vrf:
redirect: arista.eos.eos_vrf
aci_aaa_user:
redirect: cisco.aci.aci_aaa_user
aci_aaa_user_certificate:
redirect: cisco.aci.aci_aaa_user_certificate
aci_access_port_block_to_access_port:
redirect: cisco.aci.aci_access_port_block_to_access_port
aci_access_port_to_interface_policy_leaf_profile:
redirect: cisco.aci.aci_access_port_to_interface_policy_leaf_profile
aci_access_sub_port_block_to_access_port:
redirect: cisco.aci.aci_access_sub_port_block_to_access_port
aci_aep:
redirect: cisco.aci.aci_aep
aci_aep_to_domain:
redirect: cisco.aci.aci_aep_to_domain
aci_ap:
redirect: cisco.aci.aci_ap
aci_bd:
redirect: cisco.aci.aci_bd
aci_bd_subnet:
redirect: cisco.aci.aci_bd_subnet
aci_bd_to_l3out:
redirect: cisco.aci.aci_bd_to_l3out
aci_config_rollback:
redirect: cisco.aci.aci_config_rollback
aci_config_snapshot:
redirect: cisco.aci.aci_config_snapshot
aci_contract:
redirect: cisco.aci.aci_contract
aci_contract_subject:
redirect: cisco.aci.aci_contract_subject
aci_contract_subject_to_filter:
redirect: cisco.aci.aci_contract_subject_to_filter
aci_domain:
redirect: cisco.aci.aci_domain
aci_domain_to_encap_pool:
redirect: cisco.aci.aci_domain_to_encap_pool
aci_domain_to_vlan_pool:
redirect: cisco.aci.aci_domain_to_vlan_pool
aci_encap_pool:
redirect: cisco.aci.aci_encap_pool
aci_encap_pool_range:
redirect: cisco.aci.aci_encap_pool_range
aci_epg:
redirect: cisco.aci.aci_epg
aci_epg_monitoring_policy:
redirect: cisco.aci.aci_epg_monitoring_policy
aci_epg_to_contract:
redirect: cisco.aci.aci_epg_to_contract
aci_epg_to_domain:
redirect: cisco.aci.aci_epg_to_domain
aci_fabric_node:
redirect: cisco.aci.aci_fabric_node
aci_fabric_scheduler:
redirect: cisco.aci.aci_fabric_scheduler
aci_filter:
redirect: cisco.aci.aci_filter
aci_filter_entry:
redirect: cisco.aci.aci_filter_entry
aci_firmware_group:
redirect: cisco.aci.aci_firmware_group
aci_firmware_group_node:
redirect: cisco.aci.aci_firmware_group_node
aci_firmware_policy:
redirect: cisco.aci.aci_firmware_policy
aci_firmware_source:
redirect: cisco.aci.aci_firmware_source
aci_interface_policy_cdp:
redirect: cisco.aci.aci_interface_policy_cdp
aci_interface_policy_fc:
redirect: cisco.aci.aci_interface_policy_fc
aci_interface_policy_l2:
redirect: cisco.aci.aci_interface_policy_l2
aci_interface_policy_leaf_policy_group:
redirect: cisco.aci.aci_interface_policy_leaf_policy_group
aci_interface_policy_leaf_profile:
redirect: cisco.aci.aci_interface_policy_leaf_profile
aci_interface_policy_lldp:
redirect: cisco.aci.aci_interface_policy_lldp
aci_interface_policy_mcp:
redirect: cisco.aci.aci_interface_policy_mcp
aci_interface_policy_ospf:
redirect: cisco.aci.aci_interface_policy_ospf
aci_interface_policy_port_channel:
redirect: cisco.aci.aci_interface_policy_port_channel
aci_interface_policy_port_security:
redirect: cisco.aci.aci_interface_policy_port_security
aci_interface_selector_to_switch_policy_leaf_profile:
redirect: cisco.aci.aci_interface_selector_to_switch_policy_leaf_profile
aci_l3out:
redirect: cisco.aci.aci_l3out
aci_l3out_extepg:
redirect: cisco.aci.aci_l3out_extepg
aci_l3out_extsubnet:
redirect: cisco.aci.aci_l3out_extsubnet
aci_l3out_route_tag_policy:
redirect: cisco.aci.aci_l3out_route_tag_policy
aci_maintenance_group:
redirect: cisco.aci.aci_maintenance_group
aci_maintenance_group_node:
redirect: cisco.aci.aci_maintenance_group_node
aci_maintenance_policy:
redirect: cisco.aci.aci_maintenance_policy
aci_rest:
redirect: cisco.aci.aci_rest
aci_static_binding_to_epg:
redirect: cisco.aci.aci_static_binding_to_epg
aci_switch_leaf_selector:
redirect: cisco.aci.aci_switch_leaf_selector
aci_switch_policy_leaf_profile:
redirect: cisco.aci.aci_switch_policy_leaf_profile
aci_switch_policy_vpc_protection_group:
redirect: cisco.aci.aci_switch_policy_vpc_protection_group
aci_taboo_contract:
redirect: cisco.aci.aci_taboo_contract
aci_tenant:
redirect: cisco.aci.aci_tenant
aci_tenant_action_rule_profile:
redirect: cisco.aci.aci_tenant_action_rule_profile
aci_tenant_ep_retention_policy:
redirect: cisco.aci.aci_tenant_ep_retention_policy
aci_tenant_span_dst_group:
redirect: cisco.aci.aci_tenant_span_dst_group
aci_tenant_span_src_group:
redirect: cisco.aci.aci_tenant_span_src_group
aci_tenant_span_src_group_to_dst_group:
redirect: cisco.aci.aci_tenant_span_src_group_to_dst_group
aci_vlan_pool:
redirect: cisco.aci.aci_vlan_pool
aci_vlan_pool_encap_block:
redirect: cisco.aci.aci_vlan_pool_encap_block
aci_vmm_credential:
redirect: cisco.aci.aci_vmm_credential
aci_vrf:
redirect: cisco.aci.aci_vrf
asa_acl:
redirect: cisco.asa.asa_acl
asa_config:
redirect: cisco.asa.asa_config
asa_og:
redirect: cisco.asa.asa_og
asa_command:
redirect: cisco.asa.asa_command
intersight_facts:
redirect: cisco.intersight.intersight_info
intersight_info:
redirect: cisco.intersight.intersight_info
intersight_rest_api:
redirect: cisco.intersight.intersight_rest_api
ios_ospfv2:
redirect: cisco.ios.ios_ospfv2
ios_l3_interfaces:
redirect: cisco.ios.ios_l3_interfaces
ios_lldp:
redirect: cisco.ios.ios_lldp
ios_interface:
redirect: cisco.ios.ios_interface
ios_lldp_interfaces:
redirect: cisco.ios.ios_lldp_interfaces
ios_l3_interface:
redirect: cisco.ios.ios_l3_interface
ios_acl_interfaces:
redirect: cisco.ios.ios_acl_interfaces
ios_static_routes:
redirect: cisco.ios.ios_static_routes
ios_l2_interfaces:
redirect: cisco.ios.ios_l2_interfaces
ios_logging:
redirect: cisco.ios.ios_logging
ios_vlan:
redirect: cisco.ios.ios_vlan
ios_command:
redirect: cisco.ios.ios_command
ios_static_route:
redirect: cisco.ios.ios_static_route
ios_lldp_global:
redirect: cisco.ios.ios_lldp_global
ios_banner:
redirect: cisco.ios.ios_banner
ios_lag_interfaces:
redirect: cisco.ios.ios_lag_interfaces
ios_linkagg:
redirect: cisco.ios.ios_linkagg
ios_user:
redirect: cisco.ios.ios_user
ios_system:
redirect: cisco.ios.ios_system
ios_facts:
redirect: cisco.ios.ios_facts
ios_ping:
redirect: cisco.ios.ios_ping
ios_vlans:
redirect: cisco.ios.ios_vlans
ios_vrf:
redirect: cisco.ios.ios_vrf
ios_bgp:
redirect: cisco.ios.ios_bgp
ios_ntp:
redirect: cisco.ios.ios_ntp
ios_lacp_interfaces:
redirect: cisco.ios.ios_lacp_interfaces
ios_lacp:
redirect: cisco.ios.ios_lacp
ios_config:
redirect: cisco.ios.ios_config
ios_l2_interface:
redirect: cisco.ios.ios_l2_interface
ios_acls:
redirect: cisco.ios.ios_acls
ios_interfaces:
redirect: cisco.ios.ios_interfaces
iosxr_ospfv2:
redirect: cisco.iosxr.iosxr_ospfv2
iosxr_bgp:
redirect: cisco.iosxr.iosxr_bgp
iosxr_lldp_interfaces:
redirect: cisco.iosxr.iosxr_lldp_interfaces
iosxr_l3_interfaces:
redirect: cisco.iosxr.iosxr_l3_interfaces
iosxr_netconf:
redirect: cisco.iosxr.iosxr_netconf
iosxr_static_routes:
redirect: cisco.iosxr.iosxr_static_routes
iosxr_lldp_global:
redirect: cisco.iosxr.iosxr_lldp_global
iosxr_config:
redirect: cisco.iosxr.iosxr_config
iosxr_lag_interfaces:
redirect: cisco.iosxr.iosxr_lag_interfaces
iosxr_interface:
redirect: cisco.iosxr.iosxr_interface
iosxr_user:
redirect: cisco.iosxr.iosxr_user
iosxr_facts:
redirect: cisco.iosxr.iosxr_facts
iosxr_interfaces:
redirect: cisco.iosxr.iosxr_interfaces
iosxr_acl_interfaces:
redirect: cisco.iosxr.iosxr_acl_interfaces
iosxr_l2_interfaces:
redirect: cisco.iosxr.iosxr_l2_interfaces
iosxr_logging:
redirect: cisco.iosxr.iosxr_logging
iosxr_lacp:
redirect: cisco.iosxr.iosxr_lacp
iosxr_acls:
redirect: cisco.iosxr.iosxr_acls
iosxr_system:
redirect: cisco.iosxr.iosxr_system
iosxr_command:
redirect: cisco.iosxr.iosxr_command
iosxr_lacp_interfaces:
redirect: cisco.iosxr.iosxr_lacp_interfaces
iosxr_banner:
redirect: cisco.iosxr.iosxr_banner
meraki_admin:
redirect: cisco.meraki.meraki_admin
meraki_config_template:
redirect: cisco.meraki.meraki_config_template
meraki_content_filtering:
redirect: cisco.meraki.meraki_content_filtering
meraki_device:
redirect: cisco.meraki.meraki_device
meraki_firewalled_services:
redirect: cisco.meraki.meraki_firewalled_services
meraki_malware:
redirect: cisco.meraki.meraki_malware
meraki_mr_l3_firewall:
redirect: cisco.meraki.meraki_mr_l3_firewall
meraki_mx_l3_firewall:
redirect: cisco.meraki.meraki_mx_l3_firewall
meraki_mx_l7_firewall:
redirect: cisco.meraki.meraki_mx_l7_firewall
meraki_nat:
redirect: cisco.meraki.meraki_nat
meraki_network:
redirect: cisco.meraki.meraki_network
meraki_organization:
redirect: cisco.meraki.meraki_organization
meraki_snmp:
redirect: cisco.meraki.meraki_snmp
meraki_ssid:
redirect: cisco.meraki.meraki_ssid
meraki_static_route:
redirect: cisco.meraki.meraki_static_route
meraki_switchport:
redirect: cisco.meraki.meraki_switchport
meraki_syslog:
redirect: cisco.meraki.meraki_syslog
meraki_vlan:
redirect: cisco.meraki.meraki_vlan
meraki_webhook:
redirect: cisco.meraki.meraki_webhook
mso_label:
redirect: cisco.mso.mso_label
mso_role:
redirect: cisco.mso.mso_role
mso_schema:
redirect: cisco.mso.mso_schema
mso_schema_site:
redirect: cisco.mso.mso_schema_site
mso_schema_site_anp:
redirect: cisco.mso.mso_schema_site_anp
mso_schema_site_anp_epg:
redirect: cisco.mso.mso_schema_site_anp_epg
mso_schema_site_anp_epg_domain:
redirect: cisco.mso.mso_schema_site_anp_epg_domain
mso_schema_site_anp_epg_staticleaf:
redirect: cisco.mso.mso_schema_site_anp_epg_staticleaf
mso_schema_site_anp_epg_staticport:
redirect: cisco.mso.mso_schema_site_anp_epg_staticport
mso_schema_site_anp_epg_subnet:
redirect: cisco.mso.mso_schema_site_anp_epg_subnet
mso_schema_site_bd:
redirect: cisco.mso.mso_schema_site_bd
mso_schema_site_bd_l3out:
redirect: cisco.mso.mso_schema_site_bd_l3out
mso_schema_site_bd_subnet:
redirect: cisco.mso.mso_schema_site_bd_subnet
mso_schema_site_vrf:
redirect: cisco.mso.mso_schema_site_vrf
mso_schema_site_vrf_region:
redirect: cisco.mso.mso_schema_site_vrf_region
mso_schema_site_vrf_region_cidr:
redirect: cisco.mso.mso_schema_site_vrf_region_cidr
mso_schema_site_vrf_region_cidr_subnet:
redirect: cisco.mso.mso_schema_site_vrf_region_cidr_subnet
mso_schema_template:
redirect: cisco.mso.mso_schema_template
mso_schema_template_anp:
redirect: cisco.mso.mso_schema_template_anp
mso_schema_template_anp_epg:
redirect: cisco.mso.mso_schema_template_anp_epg
mso_schema_template_anp_epg_contract:
redirect: cisco.mso.mso_schema_template_anp_epg_contract
mso_schema_template_anp_epg_subnet:
redirect: cisco.mso.mso_schema_template_anp_epg_subnet
mso_schema_template_bd:
redirect: cisco.mso.mso_schema_template_bd
mso_schema_template_bd_subnet:
redirect: cisco.mso.mso_schema_template_bd_subnet
mso_schema_template_contract_filter:
redirect: cisco.mso.mso_schema_template_contract_filter
mso_schema_template_deploy:
redirect: cisco.mso.mso_schema_template_deploy
mso_schema_template_externalepg:
redirect: cisco.mso.mso_schema_template_externalepg
mso_schema_template_filter_entry:
redirect: cisco.mso.mso_schema_template_filter_entry
mso_schema_template_l3out:
redirect: cisco.mso.mso_schema_template_l3out
mso_schema_template_vrf:
redirect: cisco.mso.mso_schema_template_vrf
mso_site:
redirect: cisco.mso.mso_site
mso_tenant:
redirect: cisco.mso.mso_tenant
mso_user:
redirect: cisco.mso.mso_user
nxos_telemetry:
redirect: cisco.nxos.nxos_telemetry
nxos_user:
redirect: cisco.nxos.nxos_user
nxos_bfd_interfaces:
redirect: cisco.nxos.nxos_bfd_interfaces
nxos_ospf:
redirect: cisco.nxos.nxos_ospf
nxos_ospfv2:
redirect: cisco.nxos.nxos_ospfv2
nxos_system:
redirect: cisco.nxos.nxos_system
nxos_l3_interface:
redirect: cisco.nxos.nxos_l3_interface
nxos_smu:
redirect: cisco.nxos.nxos_smu
nxos_reboot:
redirect: cisco.nxos.nxos_reboot
nxos_static_routes:
redirect: cisco.nxos.nxos_static_routes
nxos_static_route:
redirect: cisco.nxos.nxos_static_route
nxos_acl_interfaces:
redirect: cisco.nxos.nxos_acl_interfaces
nxos_vpc:
redirect: cisco.nxos.nxos_vpc
nxos_linkagg:
redirect: cisco.nxos.nxos_linkagg
nxos_vxlan_vtep_vni:
redirect: cisco.nxos.nxos_vxlan_vtep_vni
nxos_vrrp:
redirect: cisco.nxos.nxos_vrrp
nxos_lldp:
redirect: cisco.nxos.nxos_lldp
nxos_interface:
redirect: cisco.nxos.nxos_interface
nxos_lacp_interfaces:
redirect: cisco.nxos.nxos_lacp_interfaces
nxos_gir_profile_management:
redirect: cisco.nxos.nxos_gir_profile_management
nxos_snmp_community:
redirect: cisco.nxos.nxos_snmp_community
nxos_lag_interfaces:
redirect: cisco.nxos.nxos_lag_interfaces
nxos_acl:
redirect: cisco.nxos.nxos_acl
nxos_hsrp_interfaces:
redirect: cisco.nxos.nxos_hsrp_interfaces
nxos_lldp_global:
redirect: cisco.nxos.nxos_lldp_global
nxos_snmp_contact:
redirect: cisco.nxos.nxos_snmp_contact
nxos_vrf_interface:
redirect: cisco.nxos.nxos_vrf_interface
nxos_rpm:
redirect: cisco.nxos.nxos_rpm
nxos_ntp_options:
redirect: cisco.nxos.nxos_ntp_options
nxos_ospf_vrf:
redirect: cisco.nxos.nxos_ospf_vrf
nxos_vtp_version:
redirect: cisco.nxos.nxos_vtp_version
nxos_igmp_interface:
redirect: cisco.nxos.nxos_igmp_interface
nxos_bgp_neighbor:
redirect: cisco.nxos.nxos_bgp_neighbor
nxos_bgp:
redirect: cisco.nxos.nxos_bgp
nxos_rollback:
redirect: cisco.nxos.nxos_rollback
nxos_aaa_server:
redirect: cisco.nxos.nxos_aaa_server
nxos_udld_interface:
redirect: cisco.nxos.nxos_udld_interface
nxos_bgp_af:
redirect: cisco.nxos.nxos_bgp_af
nxos_feature:
redirect: cisco.nxos.nxos_feature
nxos_snmp_traps:
redirect: cisco.nxos.nxos_snmp_traps
nxos_evpn_global:
redirect: cisco.nxos.nxos_evpn_global
nxos_igmp:
redirect: cisco.nxos.nxos_igmp
nxos_aaa_server_host:
redirect: cisco.nxos.nxos_aaa_server_host
nxos_vrf_af:
redirect: cisco.nxos.nxos_vrf_af
nxos_snapshot:
redirect: cisco.nxos.nxos_snapshot
nxos_gir:
redirect: cisco.nxos.nxos_gir
nxos_command:
redirect: cisco.nxos.nxos_command
nxos_vxlan_vtep:
redirect: cisco.nxos.nxos_vxlan_vtep
nxos_snmp_location:
redirect: cisco.nxos.nxos_snmp_location
nxos_evpn_vni:
redirect: cisco.nxos.nxos_evpn_vni
nxos_vpc_interface:
redirect: cisco.nxos.nxos_vpc_interface
nxos_logging:
redirect: cisco.nxos.nxos_logging
nxos_pim:
redirect: cisco.nxos.nxos_pim
nxos_ping:
redirect: cisco.nxos.nxos_ping
nxos_pim_rp_address:
redirect: cisco.nxos.nxos_pim_rp_address
nxos_pim_interface:
redirect: cisco.nxos.nxos_pim_interface
nxos_install_os:
redirect: cisco.nxos.nxos_install_os
nxos_nxapi:
redirect: cisco.nxos.nxos_nxapi
nxos_l2_interface:
redirect: cisco.nxos.nxos_l2_interface
nxos_bgp_neighbor_af:
redirect: cisco.nxos.nxos_bgp_neighbor_af
nxos_lacp:
redirect: cisco.nxos.nxos_lacp
nxos_lldp_interfaces:
redirect: cisco.nxos.nxos_lldp_interfaces
nxos_acl_interface:
redirect: cisco.nxos.nxos_acl_interface
nxos_vrf:
redirect: cisco.nxos.nxos_vrf
nxos_interface_ospf:
redirect: cisco.nxos.nxos_interface_ospf
nxos_acls:
redirect: cisco.nxos.nxos_acls
nxos_vtp_password:
redirect: cisco.nxos.nxos_vtp_password
nxos_l3_interfaces:
redirect: cisco.nxos.nxos_l3_interfaces
nxos_igmp_snooping:
redirect: cisco.nxos.nxos_igmp_snooping
nxos_banner:
redirect: cisco.nxos.nxos_banner
nxos_bfd_global:
redirect: cisco.nxos.nxos_bfd_global
nxos_udld:
redirect: cisco.nxos.nxos_udld
nxos_vtp_domain:
redirect: cisco.nxos.nxos_vtp_domain
nxos_snmp_host:
redirect: cisco.nxos.nxos_snmp_host
nxos_l2_interfaces:
redirect: cisco.nxos.nxos_l2_interfaces
nxos_hsrp:
redirect: cisco.nxos.nxos_hsrp
nxos_interfaces:
redirect: cisco.nxos.nxos_interfaces
nxos_overlay_global:
redirect: cisco.nxos.nxos_overlay_global
nxos_snmp_user:
redirect: cisco.nxos.nxos_snmp_user
nxos_vlans:
redirect: cisco.nxos.nxos_vlans
nxos_ntp:
redirect: cisco.nxos.nxos_ntp
nxos_file_copy:
redirect: cisco.nxos.nxos_file_copy
nxos_ntp_auth:
redirect: cisco.nxos.nxos_ntp_auth
nxos_config:
redirect: cisco.nxos.nxos_config
nxos_vlan:
redirect: cisco.nxos.nxos_vlan
nxos_facts:
redirect: cisco.nxos.nxos_facts
nxos_zone_zoneset:
redirect: cisco.nxos.nxos_zone_zoneset
nxos_vsan:
redirect: cisco.nxos.nxos_vsan
nxos_devicealias:
redirect: cisco.nxos.nxos_devicealias
ucs_managed_objects:
redirect: cisco.ucs.ucs_managed_objects
ucs_vnic_template:
redirect: cisco.ucs.ucs_vnic_template
ucs_query:
redirect: cisco.ucs.ucs_query
ucs_dns_server:
redirect: cisco.ucs.ucs_dns_server
ucs_lan_connectivity:
redirect: cisco.ucs.ucs_lan_connectivity
ucs_vhba_template:
redirect: cisco.ucs.ucs_vhba_template
ucs_san_connectivity:
redirect: cisco.ucs.ucs_san_connectivity
ucs_disk_group_policy:
redirect: cisco.ucs.ucs_disk_group_policy
ucs_uuid_pool:
redirect: cisco.ucs.ucs_uuid_pool
ucs_vlan_find:
redirect: cisco.ucs.ucs_vlan_find
ucs_vlans:
redirect: cisco.ucs.ucs_vlans
ucs_service_profile_template:
redirect: cisco.ucs.ucs_service_profile_template
ucs_ip_pool:
redirect: cisco.ucs.ucs_ip_pool
ucs_timezone:
redirect: cisco.ucs.ucs_timezone
ucs_ntp_server:
redirect: cisco.ucs.ucs_ntp_server
ucs_mac_pool:
redirect: cisco.ucs.ucs_mac_pool
ucs_storage_profile:
redirect: cisco.ucs.ucs_storage_profile
ucs_org:
redirect: cisco.ucs.ucs_org
ucs_vsans:
redirect: cisco.ucs.ucs_vsans
ucs_wwn_pool:
redirect: cisco.ucs.ucs_wwn_pool
bigip_apm_acl:
redirect: f5networks.f5_modules.bigip_apm_acl
bigip_apm_network_access:
redirect: f5networks.f5_modules.bigip_apm_network_access
bigip_apm_policy_fetch:
redirect: f5networks.f5_modules.bigip_apm_policy_fetch
bigip_apm_policy_import:
redirect: f5networks.f5_modules.bigip_apm_policy_import
bigip_appsvcs_extension:
redirect: f5networks.f5_modules.bigip_appsvcs_extension
bigip_asm_dos_application:
redirect: f5networks.f5_modules.bigip_asm_dos_application
bigip_asm_policy_fetch:
redirect: f5networks.f5_modules.bigip_asm_policy_fetch
bigip_asm_policy_import:
redirect: f5networks.f5_modules.bigip_asm_policy_import
bigip_asm_policy_manage:
redirect: f5networks.f5_modules.bigip_asm_policy_manage
bigip_asm_policy_server_technology:
redirect: f5networks.f5_modules.bigip_asm_policy_server_technology
bigip_asm_policy_signature_set:
redirect: f5networks.f5_modules.bigip_asm_policy_signature_set
bigip_cli_alias:
redirect: f5networks.f5_modules.bigip_cli_alias
bigip_cli_script:
redirect: f5networks.f5_modules.bigip_cli_script
bigip_command:
redirect: f5networks.f5_modules.bigip_command
bigip_config:
redirect: f5networks.f5_modules.bigip_config
bigip_configsync_action:
redirect: f5networks.f5_modules.bigip_configsync_action
bigip_data_group:
redirect: f5networks.f5_modules.bigip_data_group
bigip_device_auth:
redirect: f5networks.f5_modules.bigip_device_auth
bigip_device_auth_ldap:
redirect: f5networks.f5_modules.bigip_device_auth_ldap
bigip_device_certificate:
redirect: f5networks.f5_modules.bigip_device_certificate
bigip_device_connectivity:
redirect: f5networks.f5_modules.bigip_device_connectivity
bigip_device_dns:
redirect: f5networks.f5_modules.bigip_device_dns
bigip_device_group:
redirect: f5networks.f5_modules.bigip_device_group
bigip_device_group_member:
redirect: f5networks.f5_modules.bigip_device_group_member
bigip_device_ha_group:
redirect: f5networks.f5_modules.bigip_device_ha_group
bigip_device_httpd:
redirect: f5networks.f5_modules.bigip_device_httpd
bigip_device_info:
redirect: f5networks.f5_modules.bigip_device_info
bigip_device_license:
redirect: f5networks.f5_modules.bigip_device_license
bigip_device_ntp:
redirect: f5networks.f5_modules.bigip_device_ntp
bigip_device_sshd:
redirect: f5networks.f5_modules.bigip_device_sshd
bigip_device_syslog:
redirect: f5networks.f5_modules.bigip_device_syslog
bigip_device_traffic_group:
redirect: f5networks.f5_modules.bigip_device_traffic_group
bigip_device_trust:
redirect: f5networks.f5_modules.bigip_device_trust
bigip_dns_cache_resolver:
redirect: f5networks.f5_modules.bigip_dns_cache_resolver
bigip_dns_nameserver:
redirect: f5networks.f5_modules.bigip_dns_nameserver
bigip_dns_resolver:
redirect: f5networks.f5_modules.bigip_dns_resolver
bigip_dns_zone:
redirect: f5networks.f5_modules.bigip_dns_zone
bigip_file_copy:
redirect: f5networks.f5_modules.bigip_file_copy
bigip_firewall_address_list:
redirect: f5networks.f5_modules.bigip_firewall_address_list
bigip_firewall_dos_profile:
redirect: f5networks.f5_modules.bigip_firewall_dos_profile
bigip_firewall_dos_vector:
redirect: f5networks.f5_modules.bigip_firewall_dos_vector
bigip_firewall_global_rules:
redirect: f5networks.f5_modules.bigip_firewall_global_rules
bigip_firewall_log_profile:
redirect: f5networks.f5_modules.bigip_firewall_log_profile
bigip_firewall_log_profile_network:
redirect: f5networks.f5_modules.bigip_firewall_log_profile_network
bigip_firewall_policy:
redirect: f5networks.f5_modules.bigip_firewall_policy
bigip_firewall_port_list:
redirect: f5networks.f5_modules.bigip_firewall_port_list
bigip_firewall_rule:
redirect: f5networks.f5_modules.bigip_firewall_rule
bigip_firewall_rule_list:
redirect: f5networks.f5_modules.bigip_firewall_rule_list
bigip_firewall_schedule:
redirect: f5networks.f5_modules.bigip_firewall_schedule
bigip_gtm_datacenter:
redirect: f5networks.f5_modules.bigip_gtm_datacenter
bigip_gtm_global:
redirect: f5networks.f5_modules.bigip_gtm_global
bigip_gtm_monitor_bigip:
redirect: f5networks.f5_modules.bigip_gtm_monitor_bigip
bigip_gtm_monitor_external:
redirect: f5networks.f5_modules.bigip_gtm_monitor_external
bigip_gtm_monitor_firepass:
redirect: f5networks.f5_modules.bigip_gtm_monitor_firepass
bigip_gtm_monitor_http:
redirect: f5networks.f5_modules.bigip_gtm_monitor_http
bigip_gtm_monitor_https:
redirect: f5networks.f5_modules.bigip_gtm_monitor_https
bigip_gtm_monitor_tcp:
redirect: f5networks.f5_modules.bigip_gtm_monitor_tcp
bigip_gtm_monitor_tcp_half_open:
redirect: f5networks.f5_modules.bigip_gtm_monitor_tcp_half_open
bigip_gtm_pool:
redirect: f5networks.f5_modules.bigip_gtm_pool
bigip_gtm_pool_member:
redirect: f5networks.f5_modules.bigip_gtm_pool_member
bigip_gtm_server:
redirect: f5networks.f5_modules.bigip_gtm_server
bigip_gtm_topology_record:
redirect: f5networks.f5_modules.bigip_gtm_topology_record
bigip_gtm_topology_region:
redirect: f5networks.f5_modules.bigip_gtm_topology_region
bigip_gtm_virtual_server:
redirect: f5networks.f5_modules.bigip_gtm_virtual_server
bigip_gtm_wide_ip:
redirect: f5networks.f5_modules.bigip_gtm_wide_ip
bigip_hostname:
redirect: f5networks.f5_modules.bigip_hostname
bigip_iapp_service:
redirect: f5networks.f5_modules.bigip_iapp_service
bigip_iapp_template:
redirect: f5networks.f5_modules.bigip_iapp_template
bigip_ike_peer:
redirect: f5networks.f5_modules.bigip_ike_peer
bigip_imish_config:
redirect: f5networks.f5_modules.bigip_imish_config
bigip_ipsec_policy:
redirect: f5networks.f5_modules.bigip_ipsec_policy
bigip_irule:
redirect: f5networks.f5_modules.bigip_irule
bigip_log_destination:
redirect: f5networks.f5_modules.bigip_log_destination
bigip_log_publisher:
redirect: f5networks.f5_modules.bigip_log_publisher
bigip_lx_package:
redirect: f5networks.f5_modules.bigip_lx_package
bigip_management_route:
redirect: f5networks.f5_modules.bigip_management_route
bigip_message_routing_peer:
redirect: f5networks.f5_modules.bigip_message_routing_peer
bigip_message_routing_protocol:
redirect: f5networks.f5_modules.bigip_message_routing_protocol
bigip_message_routing_route:
redirect: f5networks.f5_modules.bigip_message_routing_route
bigip_message_routing_router:
redirect: f5networks.f5_modules.bigip_message_routing_router
bigip_message_routing_transport_config:
redirect: f5networks.f5_modules.bigip_message_routing_transport_config
bigip_monitor_dns:
redirect: f5networks.f5_modules.bigip_monitor_dns
bigip_monitor_external:
redirect: f5networks.f5_modules.bigip_monitor_external
bigip_monitor_gateway_icmp:
redirect: f5networks.f5_modules.bigip_monitor_gateway_icmp
bigip_monitor_http:
redirect: f5networks.f5_modules.bigip_monitor_http
bigip_monitor_https:
redirect: f5networks.f5_modules.bigip_monitor_https
bigip_monitor_ldap:
redirect: f5networks.f5_modules.bigip_monitor_ldap
bigip_monitor_snmp_dca:
redirect: f5networks.f5_modules.bigip_monitor_snmp_dca
bigip_monitor_tcp:
redirect: f5networks.f5_modules.bigip_monitor_tcp
bigip_monitor_tcp_echo:
redirect: f5networks.f5_modules.bigip_monitor_tcp_echo
bigip_monitor_tcp_half_open:
redirect: f5networks.f5_modules.bigip_monitor_tcp_half_open
bigip_monitor_udp:
redirect: f5networks.f5_modules.bigip_monitor_udp
bigip_node:
redirect: f5networks.f5_modules.bigip_node
bigip_partition:
redirect: f5networks.f5_modules.bigip_partition
bigip_password_policy:
redirect: f5networks.f5_modules.bigip_password_policy
bigip_policy:
redirect: f5networks.f5_modules.bigip_policy
bigip_policy_rule:
redirect: f5networks.f5_modules.bigip_policy_rule
bigip_pool:
redirect: f5networks.f5_modules.bigip_pool
bigip_pool_member:
redirect: f5networks.f5_modules.bigip_pool_member
bigip_profile_analytics:
redirect: f5networks.f5_modules.bigip_profile_analytics
bigip_profile_client_ssl:
redirect: f5networks.f5_modules.bigip_profile_client_ssl
bigip_profile_dns:
redirect: f5networks.f5_modules.bigip_profile_dns
bigip_profile_fastl4:
redirect: f5networks.f5_modules.bigip_profile_fastl4
bigip_profile_http:
redirect: f5networks.f5_modules.bigip_profile_http
bigip_profile_http2:
redirect: f5networks.f5_modules.bigip_profile_http2
bigip_profile_http_compression:
redirect: f5networks.f5_modules.bigip_profile_http_compression
bigip_profile_oneconnect:
redirect: f5networks.f5_modules.bigip_profile_oneconnect
bigip_profile_persistence_cookie:
redirect: f5networks.f5_modules.bigip_profile_persistence_cookie
bigip_profile_persistence_src_addr:
redirect: f5networks.f5_modules.bigip_profile_persistence_src_addr
bigip_profile_server_ssl:
redirect: f5networks.f5_modules.bigip_profile_server_ssl
bigip_profile_tcp:
redirect: f5networks.f5_modules.bigip_profile_tcp
bigip_profile_udp:
redirect: f5networks.f5_modules.bigip_profile_udp
bigip_provision:
redirect: f5networks.f5_modules.bigip_provision
bigip_qkview:
redirect: f5networks.f5_modules.bigip_qkview
bigip_remote_role:
redirect: f5networks.f5_modules.bigip_remote_role
bigip_remote_syslog:
redirect: f5networks.f5_modules.bigip_remote_syslog
bigip_remote_user:
redirect: f5networks.f5_modules.bigip_remote_user
bigip_routedomain:
redirect: f5networks.f5_modules.bigip_routedomain
bigip_selfip:
redirect: f5networks.f5_modules.bigip_selfip
bigip_service_policy:
redirect: f5networks.f5_modules.bigip_service_policy
bigip_smtp:
redirect: f5networks.f5_modules.bigip_smtp
bigip_snat_pool:
redirect: f5networks.f5_modules.bigip_snat_pool
bigip_snat_translation:
redirect: f5networks.f5_modules.bigip_snat_translation
bigip_snmp:
redirect: f5networks.f5_modules.bigip_snmp
bigip_snmp_community:
redirect: f5networks.f5_modules.bigip_snmp_community
bigip_snmp_trap:
redirect: f5networks.f5_modules.bigip_snmp_trap
bigip_software_image:
redirect: f5networks.f5_modules.bigip_software_image
bigip_software_install:
redirect: f5networks.f5_modules.bigip_software_install
bigip_software_update:
redirect: f5networks.f5_modules.bigip_software_update
bigip_ssl_certificate:
redirect: f5networks.f5_modules.bigip_ssl_certificate
bigip_ssl_key:
redirect: f5networks.f5_modules.bigip_ssl_key
bigip_ssl_ocsp:
redirect: f5networks.f5_modules.bigip_ssl_ocsp
bigip_static_route:
redirect: f5networks.f5_modules.bigip_static_route
bigip_sys_daemon_log_tmm:
redirect: f5networks.f5_modules.bigip_sys_daemon_log_tmm
bigip_sys_db:
redirect: f5networks.f5_modules.bigip_sys_db
bigip_sys_global:
redirect: f5networks.f5_modules.bigip_sys_global
bigip_timer_policy:
redirect: f5networks.f5_modules.bigip_timer_policy
bigip_traffic_selector:
redirect: f5networks.f5_modules.bigip_traffic_selector
bigip_trunk:
redirect: f5networks.f5_modules.bigip_trunk
bigip_tunnel:
redirect: f5networks.f5_modules.bigip_tunnel
bigip_ucs:
redirect: f5networks.f5_modules.bigip_ucs
bigip_ucs_fetch:
redirect: f5networks.f5_modules.bigip_ucs_fetch
bigip_user:
redirect: f5networks.f5_modules.bigip_user
bigip_vcmp_guest:
redirect: f5networks.f5_modules.bigip_vcmp_guest
bigip_virtual_address:
redirect: f5networks.f5_modules.bigip_virtual_address
bigip_virtual_server:
redirect: f5networks.f5_modules.bigip_virtual_server
bigip_vlan:
redirect: f5networks.f5_modules.bigip_vlan
bigip_wait:
redirect: f5networks.f5_modules.bigip_wait
bigiq_application_fasthttp:
redirect: f5networks.f5_modules.bigiq_application_fasthttp
bigiq_application_fastl4_tcp:
redirect: f5networks.f5_modules.bigiq_application_fastl4_tcp
bigiq_application_fastl4_udp:
redirect: f5networks.f5_modules.bigiq_application_fastl4_udp
bigiq_application_http:
redirect: f5networks.f5_modules.bigiq_application_http
bigiq_application_https_offload:
redirect: f5networks.f5_modules.bigiq_application_https_offload
bigiq_application_https_waf:
redirect: f5networks.f5_modules.bigiq_application_https_waf
bigiq_device_discovery:
redirect: f5networks.f5_modules.bigiq_device_discovery
bigiq_device_info:
redirect: f5networks.f5_modules.bigiq_device_info
bigiq_regkey_license:
redirect: f5networks.f5_modules.bigiq_regkey_license
bigiq_regkey_license_assignment:
redirect: f5networks.f5_modules.bigiq_regkey_license_assignment
bigiq_regkey_pool:
redirect: f5networks.f5_modules.bigiq_regkey_pool
bigiq_utility_license:
redirect: f5networks.f5_modules.bigiq_utility_license
bigiq_utility_license_assignment:
redirect: f5networks.f5_modules.bigiq_utility_license_assignment
os_auth:
redirect: openstack.cloud.auth
os_client_config:
redirect: openstack.cloud.config
os_coe_cluster:
redirect: openstack.cloud.coe_cluster
os_coe_cluster_template:
redirect: openstack.cloud.coe_cluster_template
os_flavor_info:
redirect: openstack.cloud.compute_flavor_info
os_floating_ip:
redirect: openstack.cloud.floating_ip
os_group:
redirect: openstack.cloud.identity_group
os_group_info:
redirect: openstack.cloud.identity_group_info
os_image:
redirect: openstack.cloud.image
os_image_info:
redirect: openstack.cloud.image_info
os_ironic:
redirect: openstack.cloud.baremetal_node
os_ironic_inspect:
redirect: openstack.cloud.baremetal_inspect
os_ironic_node:
redirect: openstack.cloud.baremetal_node_action
os_keypair:
redirect: openstack.cloud.keypair
os_keystone_domain:
redirect: openstack.cloud.identity_domain
os_keystone_domain_info:
redirect: openstack.cloud.identity_domain_info
os_keystone_endpoint:
redirect: openstack.cloud.endpoint
os_keystone_role:
redirect: openstack.cloud.identity_role
os_keystone_service:
redirect: openstack.cloud.catalog_service
os_listener:
redirect: openstack.cloud.lb_listener
os_loadbalancer:
redirect: openstack.cloud.loadbalancer
os_member:
redirect: openstack.cloud.lb_member
os_network:
redirect: openstack.cloud.network
os_networks_info:
redirect: openstack.cloud.networks_info
os_nova_flavor:
redirect: openstack.cloud.compute_flavor
os_nova_host_aggregate:
redirect: openstack.cloud.host_aggregate
os_object:
redirect: openstack.cloud.object
os_pool:
redirect: openstack.cloud.lb_pool
os_port:
redirect: openstack.cloud.port
os_port_info:
redirect: openstack.cloud.port_info
os_project:
redirect: openstack.cloud.project
os_project_access:
redirect: openstack.cloud.project_access
os_project_info:
redirect: openstack.cloud.project_info
os_quota:
redirect: openstack.cloud.quota
os_recordset:
redirect: openstack.cloud.recordset
os_router:
redirect: openstack.cloud.router
os_security_group:
redirect: openstack.cloud.security_group
os_security_group_rule:
redirect: openstack.cloud.security_group_rule
os_server:
redirect: openstack.cloud.server
os_server_action:
redirect: openstack.cloud.server_action
os_server_group:
redirect: openstack.cloud.server_group
os_server_info:
redirect: openstack.cloud.server_info
os_server_metadata:
redirect: openstack.cloud.server_metadata
os_server_volume:
redirect: openstack.cloud.server_volume
os_stack:
redirect: openstack.cloud.stack
os_subnet:
redirect: openstack.cloud.subnet
os_subnets_info:
redirect: openstack.cloud.subnets_info
os_user:
redirect: openstack.cloud.identity_user
os_user_group:
redirect: openstack.cloud.group_assignment
os_user_info:
redirect: openstack.cloud.identity_user_info
os_user_role:
redirect: openstack.cloud.role_assignment
os_volume:
redirect: openstack.cloud.volume
os_volume_snapshot:
redirect: openstack.cloud.volume_snapshot
os_zone:
redirect: openstack.cloud.dns_zone
junos_acls:
redirect: junipernetworks.junos.junos_acls
junos_acl_interfaces:
redirect: junipernetworks.junos.junos_acl_interfaces
junos_ospfv2:
redirect: junipernetworks.junos.junos_ospfv2
junos_user:
redirect: junipernetworks.junos.junos_user
junos_l2_interface:
redirect: junipernetworks.junos.junos_l2_interface
junos_lldp:
redirect: junipernetworks.junos.junos_lldp
junos_rpc:
redirect: junipernetworks.junos.junos_rpc
junos_l2_interfaces:
redirect: junipernetworks.junos.junos_l2_interfaces
junos_lldp_interface:
redirect: junipernetworks.junos.junos_lldp_interface
junos_static_route:
redirect: junipernetworks.junos.junos_static_route
junos_lacp:
redirect: junipernetworks.junos.junos_lacp
junos_lacp_interfaces:
redirect: junipernetworks.junos.junos_lacp_interfaces
junos_vlans:
redirect: junipernetworks.junos.junos_vlans
junos_linkagg:
redirect: junipernetworks.junos.junos_linkagg
junos_scp:
redirect: junipernetworks.junos.junos_scp
junos_banner:
redirect: junipernetworks.junos.junos_banner
junos_l3_interface:
redirect: junipernetworks.junos.junos_l3_interface
junos_logging:
redirect: junipernetworks.junos.junos_logging
junos_package:
redirect: junipernetworks.junos.junos_package
junos_netconf:
redirect: junipernetworks.junos.junos_netconf
junos_facts:
redirect: junipernetworks.junos.junos_facts
junos_ping:
redirect: junipernetworks.junos.junos_ping
junos_interface:
redirect: junipernetworks.junos.junos_interface
junos_lldp_global:
redirect: junipernetworks.junos.junos_lldp_global
junos_config:
redirect: junipernetworks.junos.junos_config
junos_static_routes:
redirect: junipernetworks.junos.junos_static_routes
junos_command:
redirect: junipernetworks.junos.junos_command
junos_lag_interfaces:
redirect: junipernetworks.junos.junos_lag_interfaces
junos_l3_interfaces:
redirect: junipernetworks.junos.junos_l3_interfaces
junos_lldp_interfaces:
redirect: junipernetworks.junos.junos_lldp_interfaces
junos_vlan:
redirect: junipernetworks.junos.junos_vlan
junos_system:
redirect: junipernetworks.junos.junos_system
junos_interfaces:
redirect: junipernetworks.junos.junos_interfaces
junos_vrf:
redirect: junipernetworks.junos.junos_vrf
tower_credential:
redirect: awx.awx.tower_credential
tower_credential_type:
redirect: awx.awx.tower_credential_type
tower_group:
redirect: awx.awx.tower_group
tower_host:
redirect: awx.awx.tower_host
tower_inventory:
redirect: awx.awx.tower_inventory
tower_inventory_source:
redirect: awx.awx.tower_inventory_source
tower_job_cancel:
redirect: awx.awx.tower_job_cancel
tower_job_launch:
redirect: awx.awx.tower_job_launch
tower_job_list:
redirect: awx.awx.tower_job_list
tower_job_template:
redirect: awx.awx.tower_job_template
tower_job_wait:
redirect: awx.awx.tower_job_wait
tower_label:
redirect: awx.awx.tower_label
tower_notification:
redirect: awx.awx.tower_notification
tower_organization:
redirect: awx.awx.tower_organization
tower_project:
redirect: awx.awx.tower_project
tower_receive:
redirect: awx.awx.tower_receive
tower_role:
redirect: awx.awx.tower_role
tower_send:
redirect: awx.awx.tower_send
tower_settings:
redirect: awx.awx.tower_settings
tower_team:
redirect: awx.awx.tower_team
tower_user:
redirect: awx.awx.tower_user
tower_workflow_launch:
redirect: awx.awx.tower_workflow_launch
tower_workflow_template:
redirect: awx.awx.tower_workflow_template
ovirt_affinity_group:
redirect: ovirt.ovirt.ovirt_affinity_group
ovirt_affinity_label:
redirect: ovirt.ovirt.ovirt_affinity_label
ovirt_affinity_label_info:
redirect: ovirt.ovirt.ovirt_affinity_label_info
ovirt_api_info:
redirect: ovirt.ovirt.ovirt_api_info
ovirt_auth:
redirect: ovirt.ovirt.ovirt_auth
ovirt_cluster:
redirect: ovirt.ovirt.ovirt_cluster
ovirt_cluster_info:
redirect: ovirt.ovirt.ovirt_cluster_info
ovirt_datacenter:
redirect: ovirt.ovirt.ovirt_datacenter
ovirt_datacenter_info:
redirect: ovirt.ovirt.ovirt_datacenter_info
ovirt_disk:
redirect: ovirt.ovirt.ovirt_disk
ovirt_disk_info:
redirect: ovirt.ovirt.ovirt_disk_info
ovirt_event:
redirect: ovirt.ovirt.ovirt_event
ovirt_event_info:
redirect: ovirt.ovirt.ovirt_event_info
ovirt_external_provider:
redirect: ovirt.ovirt.ovirt_external_provider
ovirt_external_provider_info:
redirect: ovirt.ovirt.ovirt_external_provider_info
ovirt_group:
redirect: ovirt.ovirt.ovirt_group
ovirt_group_info:
redirect: ovirt.ovirt.ovirt_group_info
ovirt_host:
redirect: ovirt.ovirt.ovirt_host
ovirt_host_info:
redirect: ovirt.ovirt.ovirt_host_info
ovirt_host_network:
redirect: ovirt.ovirt.ovirt_host_network
ovirt_host_pm:
redirect: ovirt.ovirt.ovirt_host_pm
ovirt_host_storage_info:
redirect: ovirt.ovirt.ovirt_host_storage_info
ovirt_instance_type:
redirect: ovirt.ovirt.ovirt_instance_type
ovirt_job:
redirect: ovirt.ovirt.ovirt_job
ovirt_mac_pool:
redirect: ovirt.ovirt.ovirt_mac_pool
ovirt_network:
redirect: ovirt.ovirt.ovirt_network
ovirt_network_info:
redirect: ovirt.ovirt.ovirt_network_info
ovirt_nic:
redirect: ovirt.ovirt.ovirt_nic
ovirt_nic_info:
redirect: ovirt.ovirt.ovirt_nic_info
ovirt_permission:
redirect: ovirt.ovirt.ovirt_permission
ovirt_permission_info:
redirect: ovirt.ovirt.ovirt_permission_info
ovirt_quota:
redirect: ovirt.ovirt.ovirt_quota
ovirt_quota_info:
redirect: ovirt.ovirt.ovirt_quota_info
ovirt_role:
redirect: ovirt.ovirt.ovirt_role
ovirt_scheduling_policy_info:
redirect: ovirt.ovirt.ovirt_scheduling_policy_info
ovirt_snapshot:
redirect: ovirt.ovirt.ovirt_snapshot
ovirt_snapshot_info:
redirect: ovirt.ovirt.ovirt_snapshot_info
ovirt_storage_connection:
redirect: ovirt.ovirt.ovirt_storage_connection
ovirt_storage_domain:
redirect: ovirt.ovirt.ovirt_storage_domain
ovirt_storage_domain_info:
redirect: ovirt.ovirt.ovirt_storage_domain_info
ovirt_storage_template_info:
redirect: ovirt.ovirt.ovirt_storage_template_info
ovirt_storage_vm_info:
redirect: ovirt.ovirt.ovirt_storage_vm_info
ovirt_tag:
redirect: ovirt.ovirt.ovirt_tag
ovirt_tag_info:
redirect: ovirt.ovirt.ovirt_tag_info
ovirt_template:
redirect: ovirt.ovirt.ovirt_template
ovirt_template_info:
redirect: ovirt.ovirt.ovirt_template_info
ovirt_user:
redirect: ovirt.ovirt.ovirt_user
ovirt_user_info:
redirect: ovirt.ovirt.ovirt_user_info
ovirt_vm:
redirect: ovirt.ovirt.ovirt_vm
ovirt_vm_info:
redirect: ovirt.ovirt.ovirt_vm_info
ovirt_vmpool:
redirect: ovirt.ovirt.ovirt_vmpool
ovirt_vmpool_info:
redirect: ovirt.ovirt.ovirt_vmpool_info
ovirt_vnic_profile:
redirect: ovirt.ovirt.ovirt_vnic_profile
ovirt_vnic_profile_info:
redirect: ovirt.ovirt.ovirt_vnic_profile_info
dellos10_command:
redirect: dellemc.os10.os10_command
dellos10_facts:
redirect: dellemc.os10.os10_facts
dellos10_config:
redirect: dellemc.os10.os10_config
dellos9_facts:
redirect: dellemc.os9.os9_facts
dellos9_command:
redirect: dellemc.os9.os9_command
dellos9_config:
redirect: dellemc.os9.os9_config
dellos6_facts:
redirect: dellemc.os6.os6_facts
dellos6_config:
redirect: dellemc.os6.os6_config
dellos6_command:
redirect: dellemc.os6.os6_command
hcloud_location_facts:
redirect: hetzner.hcloud.hcloud_location_facts
hcloud_server_info:
redirect: hetzner.hcloud.hcloud_server_info
hcloud_server_network:
redirect: hetzner.hcloud.hcloud_server_network
hcloud_server_type_info:
redirect: hetzner.hcloud.hcloud_server_type_info
hcloud_route:
redirect: hetzner.hcloud.hcloud_route
hcloud_server:
redirect: hetzner.hcloud.hcloud_server
hcloud_volume_info:
redirect: hetzner.hcloud.hcloud_volume_info
hcloud_server_type_facts:
redirect: hetzner.hcloud.hcloud_server_type_facts
hcloud_ssh_key_info:
redirect: hetzner.hcloud.hcloud_ssh_key_info
hcloud_network_info:
redirect: hetzner.hcloud.hcloud_network_info
hcloud_datacenter_info:
redirect: hetzner.hcloud.hcloud_datacenter_info
hcloud_image_facts:
redirect: hetzner.hcloud.hcloud_image_facts
hcloud_volume_facts:
redirect: hetzner.hcloud.hcloud_volume_facts
hcloud_floating_ip_info:
redirect: hetzner.hcloud.hcloud_floating_ip_info
hcloud_floating_ip_facts:
redirect: hetzner.hcloud.hcloud_floating_ip_facts
hcloud_image_info:
redirect: hetzner.hcloud.hcloud_image_info
hcloud_ssh_key_facts:
redirect: hetzner.hcloud.hcloud_ssh_key_facts
hcloud_location_info:
redirect: hetzner.hcloud.hcloud_location_info
hcloud_network:
redirect: hetzner.hcloud.hcloud_network
hcloud_volume:
redirect: hetzner.hcloud.hcloud_volume
hcloud_ssh_key:
redirect: hetzner.hcloud.hcloud_ssh_key
hcloud_datacenter_facts:
redirect: hetzner.hcloud.hcloud_datacenter_facts
hcloud_rdns:
redirect: hetzner.hcloud.hcloud_rdns
hcloud_floating_ip:
redirect: hetzner.hcloud.hcloud_floating_ip
hcloud_server_facts:
redirect: hetzner.hcloud.hcloud_server_facts
hcloud_subnetwork:
redirect: hetzner.hcloud.hcloud_subnetwork
skydive_capture:
redirect: community.skydive.skydive_capture
skydive_edge:
redirect: community.skydive.skydive_edge
skydive_node:
redirect: community.skydive.skydive_node
cyberark_authentication:
redirect: cyberark.pas.cyberark_authentication
cyberark_user:
redirect: cyberark.pas.cyberark_user
gcp_appengine_firewall_rule:
redirect: google.cloud.gcp_appengine_firewall_rule
gcp_appengine_firewall_rule_info:
redirect: google.cloud.gcp_appengine_firewall_rule_info
gcp_bigquery_dataset:
redirect: google.cloud.gcp_bigquery_dataset
gcp_bigquery_dataset_info:
redirect: google.cloud.gcp_bigquery_dataset_info
gcp_bigquery_table:
redirect: google.cloud.gcp_bigquery_table
gcp_bigquery_table_info:
redirect: google.cloud.gcp_bigquery_table_info
gcp_cloudbuild_trigger:
redirect: google.cloud.gcp_cloudbuild_trigger
gcp_cloudbuild_trigger_info:
redirect: google.cloud.gcp_cloudbuild_trigger_info
gcp_cloudfunctions_cloud_function:
redirect: google.cloud.gcp_cloudfunctions_cloud_function
gcp_cloudfunctions_cloud_function_info:
redirect: google.cloud.gcp_cloudfunctions_cloud_function_info
gcp_cloudscheduler_job:
redirect: google.cloud.gcp_cloudscheduler_job
gcp_cloudscheduler_job_info:
redirect: google.cloud.gcp_cloudscheduler_job_info
gcp_cloudtasks_queue:
redirect: google.cloud.gcp_cloudtasks_queue
gcp_cloudtasks_queue_info:
redirect: google.cloud.gcp_cloudtasks_queue_info
gcp_compute_address:
redirect: google.cloud.gcp_compute_address
gcp_compute_address_info:
redirect: google.cloud.gcp_compute_address_info
gcp_compute_autoscaler:
redirect: google.cloud.gcp_compute_autoscaler
gcp_compute_autoscaler_info:
redirect: google.cloud.gcp_compute_autoscaler_info
gcp_compute_backend_bucket:
redirect: google.cloud.gcp_compute_backend_bucket
gcp_compute_backend_bucket_info:
redirect: google.cloud.gcp_compute_backend_bucket_info
gcp_compute_backend_service:
redirect: google.cloud.gcp_compute_backend_service
gcp_compute_backend_service_info:
redirect: google.cloud.gcp_compute_backend_service_info
gcp_compute_disk:
redirect: google.cloud.gcp_compute_disk
gcp_compute_disk_info:
redirect: google.cloud.gcp_compute_disk_info
gcp_compute_firewall:
redirect: google.cloud.gcp_compute_firewall
gcp_compute_firewall_info:
redirect: google.cloud.gcp_compute_firewall_info
gcp_compute_forwarding_rule:
redirect: google.cloud.gcp_compute_forwarding_rule
gcp_compute_forwarding_rule_info:
redirect: google.cloud.gcp_compute_forwarding_rule_info
gcp_compute_global_address:
redirect: google.cloud.gcp_compute_global_address
gcp_compute_global_address_info:
redirect: google.cloud.gcp_compute_global_address_info
gcp_compute_global_forwarding_rule:
redirect: google.cloud.gcp_compute_global_forwarding_rule
gcp_compute_global_forwarding_rule_info:
redirect: google.cloud.gcp_compute_global_forwarding_rule_info
gcp_compute_health_check:
redirect: google.cloud.gcp_compute_health_check
gcp_compute_health_check_info:
redirect: google.cloud.gcp_compute_health_check_info
gcp_compute_http_health_check:
redirect: google.cloud.gcp_compute_http_health_check
gcp_compute_http_health_check_info:
redirect: google.cloud.gcp_compute_http_health_check_info
gcp_compute_https_health_check:
redirect: google.cloud.gcp_compute_https_health_check
gcp_compute_https_health_check_info:
redirect: google.cloud.gcp_compute_https_health_check_info
gcp_compute_image:
redirect: google.cloud.gcp_compute_image
gcp_compute_image_info:
redirect: google.cloud.gcp_compute_image_info
gcp_compute_instance:
redirect: google.cloud.gcp_compute_instance
gcp_compute_instance_group:
redirect: google.cloud.gcp_compute_instance_group
gcp_compute_instance_group_info:
redirect: google.cloud.gcp_compute_instance_group_info
gcp_compute_instance_group_manager:
redirect: google.cloud.gcp_compute_instance_group_manager
gcp_compute_instance_group_manager_info:
redirect: google.cloud.gcp_compute_instance_group_manager_info
gcp_compute_instance_info:
redirect: google.cloud.gcp_compute_instance_info
gcp_compute_instance_template:
redirect: google.cloud.gcp_compute_instance_template
gcp_compute_instance_template_info:
redirect: google.cloud.gcp_compute_instance_template_info
gcp_compute_interconnect_attachment:
redirect: google.cloud.gcp_compute_interconnect_attachment
gcp_compute_interconnect_attachment_info:
redirect: google.cloud.gcp_compute_interconnect_attachment_info
gcp_compute_network:
redirect: google.cloud.gcp_compute_network
gcp_compute_network_endpoint_group:
redirect: google.cloud.gcp_compute_network_endpoint_group
gcp_compute_network_endpoint_group_info:
redirect: google.cloud.gcp_compute_network_endpoint_group_info
gcp_compute_network_info:
redirect: google.cloud.gcp_compute_network_info
gcp_compute_node_group:
redirect: google.cloud.gcp_compute_node_group
gcp_compute_node_group_info:
redirect: google.cloud.gcp_compute_node_group_info
gcp_compute_node_template:
redirect: google.cloud.gcp_compute_node_template
gcp_compute_node_template_info:
redirect: google.cloud.gcp_compute_node_template_info
gcp_compute_region_backend_service:
redirect: google.cloud.gcp_compute_region_backend_service
gcp_compute_region_backend_service_info:
redirect: google.cloud.gcp_compute_region_backend_service_info
gcp_compute_region_disk:
redirect: google.cloud.gcp_compute_region_disk
gcp_compute_region_disk_info:
redirect: google.cloud.gcp_compute_region_disk_info
gcp_compute_reservation:
redirect: google.cloud.gcp_compute_reservation
gcp_compute_reservation_info:
redirect: google.cloud.gcp_compute_reservation_info
gcp_compute_route:
redirect: google.cloud.gcp_compute_route
gcp_compute_route_info:
redirect: google.cloud.gcp_compute_route_info
gcp_compute_router:
redirect: google.cloud.gcp_compute_router
gcp_compute_router_info:
redirect: google.cloud.gcp_compute_router_info
gcp_compute_snapshot:
redirect: google.cloud.gcp_compute_snapshot
gcp_compute_snapshot_info:
redirect: google.cloud.gcp_compute_snapshot_info
gcp_compute_ssl_certificate:
redirect: google.cloud.gcp_compute_ssl_certificate
gcp_compute_ssl_certificate_info:
redirect: google.cloud.gcp_compute_ssl_certificate_info
gcp_compute_ssl_policy:
redirect: google.cloud.gcp_compute_ssl_policy
gcp_compute_ssl_policy_info:
redirect: google.cloud.gcp_compute_ssl_policy_info
gcp_compute_subnetwork:
redirect: google.cloud.gcp_compute_subnetwork
gcp_compute_subnetwork_info:
redirect: google.cloud.gcp_compute_subnetwork_info
gcp_compute_target_http_proxy:
redirect: google.cloud.gcp_compute_target_http_proxy
gcp_compute_target_http_proxy_info:
redirect: google.cloud.gcp_compute_target_http_proxy_info
gcp_compute_target_https_proxy:
redirect: google.cloud.gcp_compute_target_https_proxy
gcp_compute_target_https_proxy_info:
redirect: google.cloud.gcp_compute_target_https_proxy_info
gcp_compute_target_instance:
redirect: google.cloud.gcp_compute_target_instance
gcp_compute_target_instance_info:
redirect: google.cloud.gcp_compute_target_instance_info
gcp_compute_target_pool:
redirect: google.cloud.gcp_compute_target_pool
gcp_compute_target_pool_info:
redirect: google.cloud.gcp_compute_target_pool_info
gcp_compute_target_ssl_proxy:
redirect: google.cloud.gcp_compute_target_ssl_proxy
gcp_compute_target_ssl_proxy_info:
redirect: google.cloud.gcp_compute_target_ssl_proxy_info
gcp_compute_target_tcp_proxy:
redirect: google.cloud.gcp_compute_target_tcp_proxy
gcp_compute_target_tcp_proxy_info:
redirect: google.cloud.gcp_compute_target_tcp_proxy_info
gcp_compute_target_vpn_gateway:
redirect: google.cloud.gcp_compute_target_vpn_gateway
gcp_compute_target_vpn_gateway_info:
redirect: google.cloud.gcp_compute_target_vpn_gateway_info
gcp_compute_url_map:
redirect: google.cloud.gcp_compute_url_map
gcp_compute_url_map_info:
redirect: google.cloud.gcp_compute_url_map_info
gcp_compute_vpn_tunnel:
redirect: google.cloud.gcp_compute_vpn_tunnel
gcp_compute_vpn_tunnel_info:
redirect: google.cloud.gcp_compute_vpn_tunnel_info
gcp_container_cluster:
redirect: google.cloud.gcp_container_cluster
gcp_container_cluster_info:
redirect: google.cloud.gcp_container_cluster_info
gcp_container_node_pool:
redirect: google.cloud.gcp_container_node_pool
gcp_container_node_pool_info:
redirect: google.cloud.gcp_container_node_pool_info
gcp_dns_managed_zone:
redirect: google.cloud.gcp_dns_managed_zone
gcp_dns_managed_zone_info:
redirect: google.cloud.gcp_dns_managed_zone_info
gcp_dns_resource_record_set:
redirect: google.cloud.gcp_dns_resource_record_set
gcp_dns_resource_record_set_info:
redirect: google.cloud.gcp_dns_resource_record_set_info
gcp_filestore_instance:
redirect: google.cloud.gcp_filestore_instance
gcp_filestore_instance_info:
redirect: google.cloud.gcp_filestore_instance_info
gcp_iam_role:
redirect: google.cloud.gcp_iam_role
gcp_iam_role_info:
redirect: google.cloud.gcp_iam_role_info
gcp_iam_service_account:
redirect: google.cloud.gcp_iam_service_account
gcp_iam_service_account_info:
redirect: google.cloud.gcp_iam_service_account_info
gcp_iam_service_account_key:
redirect: google.cloud.gcp_iam_service_account_key
gcp_kms_crypto_key:
redirect: google.cloud.gcp_kms_crypto_key
gcp_kms_crypto_key_info:
redirect: google.cloud.gcp_kms_crypto_key_info
gcp_kms_key_ring:
redirect: google.cloud.gcp_kms_key_ring
gcp_kms_key_ring_info:
redirect: google.cloud.gcp_kms_key_ring_info
gcp_logging_metric:
redirect: google.cloud.gcp_logging_metric
gcp_logging_metric_info:
redirect: google.cloud.gcp_logging_metric_info
gcp_mlengine_model:
redirect: google.cloud.gcp_mlengine_model
gcp_mlengine_model_info:
redirect: google.cloud.gcp_mlengine_model_info
gcp_mlengine_version:
redirect: google.cloud.gcp_mlengine_version
gcp_mlengine_version_info:
redirect: google.cloud.gcp_mlengine_version_info
gcp_pubsub_subscription:
redirect: google.cloud.gcp_pubsub_subscription
gcp_pubsub_subscription_info:
redirect: google.cloud.gcp_pubsub_subscription_info
gcp_pubsub_topic:
redirect: google.cloud.gcp_pubsub_topic
gcp_pubsub_topic_info:
redirect: google.cloud.gcp_pubsub_topic_info
gcp_redis_instance:
redirect: google.cloud.gcp_redis_instance
gcp_redis_instance_info:
redirect: google.cloud.gcp_redis_instance_info
gcp_resourcemanager_project:
redirect: google.cloud.gcp_resourcemanager_project
gcp_resourcemanager_project_info:
redirect: google.cloud.gcp_resourcemanager_project_info
gcp_runtimeconfig_config:
redirect: google.cloud.gcp_runtimeconfig_config
gcp_runtimeconfig_config_info:
redirect: google.cloud.gcp_runtimeconfig_config_info
gcp_runtimeconfig_variable:
redirect: google.cloud.gcp_runtimeconfig_variable
gcp_runtimeconfig_variable_info:
redirect: google.cloud.gcp_runtimeconfig_variable_info
gcp_serviceusage_service:
redirect: google.cloud.gcp_serviceusage_service
gcp_serviceusage_service_info:
redirect: google.cloud.gcp_serviceusage_service_info
gcp_sourcerepo_repository:
redirect: google.cloud.gcp_sourcerepo_repository
gcp_sourcerepo_repository_info:
redirect: google.cloud.gcp_sourcerepo_repository_info
gcp_spanner_database:
redirect: google.cloud.gcp_spanner_database
gcp_spanner_database_info:
redirect: google.cloud.gcp_spanner_database_info
gcp_spanner_instance:
redirect: google.cloud.gcp_spanner_instance
gcp_spanner_instance_info:
redirect: google.cloud.gcp_spanner_instance_info
gcp_sql_database:
redirect: google.cloud.gcp_sql_database
gcp_sql_database_info:
redirect: google.cloud.gcp_sql_database_info
gcp_sql_instance:
redirect: google.cloud.gcp_sql_instance
gcp_sql_instance_info:
redirect: google.cloud.gcp_sql_instance_info
gcp_sql_user:
redirect: google.cloud.gcp_sql_user
gcp_sql_user_info:
redirect: google.cloud.gcp_sql_user_info
gcp_storage_bucket:
redirect: google.cloud.gcp_storage_bucket
gcp_storage_bucket_access_control:
redirect: google.cloud.gcp_storage_bucket_access_control
gcp_storage_object:
redirect: google.cloud.gcp_storage_object
gcp_tpu_node:
redirect: google.cloud.gcp_tpu_node
gcp_tpu_node_info:
redirect: google.cloud.gcp_tpu_node_info
purefa_alert:
redirect: purestorage.flasharray.purefa_alert
purefa_arrayname:
redirect: purestorage.flasharray.purefa_arrayname
purefa_banner:
redirect: purestorage.flasharray.purefa_banner
purefa_connect:
redirect: purestorage.flasharray.purefa_connect
purefa_dns:
redirect: purestorage.flasharray.purefa_dns
purefa_ds:
redirect: purestorage.flasharray.purefa_ds
purefa_dsrole:
redirect: purestorage.flasharray.purefa_dsrole
purefa_hg:
redirect: purestorage.flasharray.purefa_hg
purefa_host:
redirect: purestorage.flasharray.purefa_host
purefa_info:
redirect: purestorage.flasharray.purefa_info
purefa_ntp:
redirect: purestorage.flasharray.purefa_ntp
purefa_offload:
redirect: purestorage.flasharray.purefa_offload
purefa_pg:
redirect: purestorage.flasharray.purefa_pg
purefa_pgsnap:
redirect: purestorage.flasharray.purefa_pgsnap
purefa_phonehome:
redirect: purestorage.flasharray.purefa_phonehome
purefa_ra:
redirect: purestorage.flasharray.purefa_ra
purefa_smtp:
redirect: purestorage.flasharray.purefa_smtp
purefa_snap:
redirect: purestorage.flasharray.purefa_snap
purefa_snmp:
redirect: purestorage.flasharray.purefa_snmp
purefa_syslog:
redirect: purestorage.flasharray.purefa_syslog
purefa_user:
redirect: purestorage.flasharray.purefa_user
purefa_vg:
redirect: purestorage.flasharray.purefa_vg
purefa_volume:
redirect: purestorage.flasharray.purefa_volume
purefb_bucket:
redirect: purestorage.flashblade.purefb_bucket
purefb_ds:
redirect: purestorage.flashblade.purefb_ds
purefb_dsrole:
redirect: purestorage.flashblade.purefb_dsrole
purefb_fs:
redirect: purestorage.flashblade.purefb_fs
purefb_info:
redirect: purestorage.flashblade.purefb_info
purefb_network:
redirect: purestorage.flashblade.purefb_network
purefb_ra:
redirect: purestorage.flashblade.purefb_ra
purefb_s3acc:
redirect: purestorage.flashblade.purefb_s3acc
purefb_s3user:
redirect: purestorage.flashblade.purefb_s3user
purefb_smtp:
redirect: purestorage.flashblade.purefb_smtp
purefb_snap:
redirect: purestorage.flashblade.purefb_snap
purefb_subnet:
redirect: purestorage.flashblade.purefb_subnet
azure_rm_acs:
redirect: azure.azcollection.azure_rm_acs
azure_rm_virtualmachine_info:
redirect: azure.azcollection.azure_rm_virtualmachine_info
azure_rm_dnsrecordset_info:
redirect: azure.azcollection.azure_rm_dnsrecordset_info
azure_rm_dnszone_info:
redirect: azure.azcollection.azure_rm_dnszone_info
azure_rm_networkinterface_info:
redirect: azure.azcollection.azure_rm_networkinterface_info
azure_rm_publicipaddress_info:
redirect: azure.azcollection.azure_rm_publicipaddress_info
azure_rm_securitygroup_info:
redirect: azure.azcollection.azure_rm_securitygroup_info
azure_rm_storageaccount_info:
redirect: azure.azcollection.azure_rm_storageaccount_info
azure_rm_virtualnetwork_info:
redirect: azure.azcollection.azure_rm_virtualnetwork_info
azure_rm_deployment:
redirect: azure.azcollection.azure_rm_deployment
azure_rm_dnsrecordset:
redirect: azure.azcollection.azure_rm_dnsrecordset
azure_rm_dnszone:
redirect: azure.azcollection.azure_rm_dnszone
azure_rm_networkinterface:
redirect: azure.azcollection.azure_rm_networkinterface
azure_rm_publicipaddress:
redirect: azure.azcollection.azure_rm_publicipaddress
azure_rm_securitygroup:
redirect: azure.azcollection.azure_rm_securitygroup
azure_rm_storageaccount:
redirect: azure.azcollection.azure_rm_storageaccount
azure_rm_subnet:
redirect: azure.azcollection.azure_rm_subnet
azure_rm_virtualmachine:
redirect: azure.azcollection.azure_rm_virtualmachine
azure_rm_virtualnetwork:
redirect: azure.azcollection.azure_rm_virtualnetwork
azure_rm_aks:
redirect: azure.azcollection.azure_rm_aks
azure_rm_aks_info:
redirect: azure.azcollection.azure_rm_aks_info
azure_rm_aksversion_info:
redirect: azure.azcollection.azure_rm_aksversion_info
azure_rm_appgateway:
redirect: azure.azcollection.azure_rm_appgateway
azure_rm_applicationsecuritygroup:
redirect: azure.azcollection.azure_rm_applicationsecuritygroup
azure_rm_applicationsecuritygroup_info:
redirect: azure.azcollection.azure_rm_applicationsecuritygroup_info
azure_rm_appserviceplan:
redirect: azure.azcollection.azure_rm_appserviceplan
azure_rm_appserviceplan_info:
redirect: azure.azcollection.azure_rm_appserviceplan_info
azure_rm_availabilityset:
redirect: azure.azcollection.azure_rm_availabilityset
azure_rm_availabilityset_info:
redirect: azure.azcollection.azure_rm_availabilityset_info
azure_rm_containerinstance:
redirect: azure.azcollection.azure_rm_containerinstance
azure_rm_containerinstance_info:
redirect: azure.azcollection.azure_rm_containerinstance_info
azure_rm_containerregistry:
redirect: azure.azcollection.azure_rm_containerregistry
azure_rm_containerregistry_info:
redirect: azure.azcollection.azure_rm_containerregistry_info
azure_rm_deployment_info:
redirect: azure.azcollection.azure_rm_deployment_info
azure_rm_functionapp:
redirect: azure.azcollection.azure_rm_functionapp
azure_rm_functionapp_info:
redirect: azure.azcollection.azure_rm_functionapp_info
azure_rm_gallery:
redirect: azure.azcollection.azure_rm_gallery
azure_rm_gallery_info:
redirect: azure.azcollection.azure_rm_gallery_info
azure_rm_galleryimage:
redirect: azure.azcollection.azure_rm_galleryimage
azure_rm_galleryimage_info:
redirect: azure.azcollection.azure_rm_galleryimage_info
azure_rm_galleryimageversion:
redirect: azure.azcollection.azure_rm_galleryimageversion
azure_rm_galleryimageversion_info:
redirect: azure.azcollection.azure_rm_galleryimageversion_info
azure_rm_image:
redirect: azure.azcollection.azure_rm_image
azure_rm_image_info:
redirect: azure.azcollection.azure_rm_image_info
azure_rm_keyvault:
redirect: azure.azcollection.azure_rm_keyvault
azure_rm_keyvault_info:
redirect: azure.azcollection.azure_rm_keyvault_info
azure_rm_keyvaultkey:
redirect: azure.azcollection.azure_rm_keyvaultkey
azure_rm_keyvaultkey_info:
redirect: azure.azcollection.azure_rm_keyvaultkey_info
azure_rm_keyvaultsecret:
redirect: azure.azcollection.azure_rm_keyvaultsecret
azure_rm_manageddisk:
redirect: azure.azcollection.azure_rm_manageddisk
azure_rm_manageddisk_info:
redirect: azure.azcollection.azure_rm_manageddisk_info
azure_rm_resource:
redirect: azure.azcollection.azure_rm_resource
azure_rm_resource_info:
redirect: azure.azcollection.azure_rm_resource_info
azure_rm_resourcegroup:
redirect: azure.azcollection.azure_rm_resourcegroup
azure_rm_resourcegroup_info:
redirect: azure.azcollection.azure_rm_resourcegroup_info
azure_rm_snapshot:
redirect: azure.azcollection.azure_rm_snapshot
azure_rm_storageblob:
redirect: azure.azcollection.azure_rm_storageblob
azure_rm_subnet_info:
redirect: azure.azcollection.azure_rm_subnet_info
azure_rm_virtualmachineextension:
redirect: azure.azcollection.azure_rm_virtualmachineextension
azure_rm_virtualmachineextension_info:
redirect: azure.azcollection.azure_rm_virtualmachineextension_info
azure_rm_virtualmachineimage_info:
redirect: azure.azcollection.azure_rm_virtualmachineimage_info
azure_rm_virtualmachinescaleset:
redirect: azure.azcollection.azure_rm_virtualmachinescaleset
azure_rm_virtualmachinescaleset_info:
redirect: azure.azcollection.azure_rm_virtualmachinescaleset_info
azure_rm_virtualmachinescalesetextension:
redirect: azure.azcollection.azure_rm_virtualmachinescalesetextension
azure_rm_virtualmachinescalesetextension_info:
redirect: azure.azcollection.azure_rm_virtualmachinescalesetextension_info
azure_rm_virtualmachinescalesetinstance:
redirect: azure.azcollection.azure_rm_virtualmachinescalesetinstance
azure_rm_virtualmachinescalesetinstance_info:
redirect: azure.azcollection.azure_rm_virtualmachinescalesetinstance_info
azure_rm_webapp:
redirect: azure.azcollection.azure_rm_webapp
azure_rm_webapp_info:
redirect: azure.azcollection.azure_rm_webapp_info
azure_rm_webappslot:
redirect: azure.azcollection.azure_rm_webappslot
azure_rm_automationaccount:
redirect: azure.azcollection.azure_rm_automationaccount
azure_rm_automationaccount_info:
redirect: azure.azcollection.azure_rm_automationaccount_info
azure_rm_autoscale:
redirect: azure.azcollection.azure_rm_autoscale
azure_rm_autoscale_info:
redirect: azure.azcollection.azure_rm_autoscale_info
azure_rm_azurefirewall:
redirect: azure.azcollection.azure_rm_azurefirewall
azure_rm_azurefirewall_info:
redirect: azure.azcollection.azure_rm_azurefirewall_info
azure_rm_batchaccount:
redirect: azure.azcollection.azure_rm_batchaccount
azure_rm_cdnendpoint:
redirect: azure.azcollection.azure_rm_cdnendpoint
azure_rm_cdnendpoint_info:
redirect: azure.azcollection.azure_rm_cdnendpoint_info
azure_rm_cdnprofile:
redirect: azure.azcollection.azure_rm_cdnprofile
azure_rm_cdnprofile_info:
redirect: azure.azcollection.azure_rm_cdnprofile_info
azure_rm_iotdevice:
redirect: azure.azcollection.azure_rm_iotdevice
azure_rm_iotdevice_info:
redirect: azure.azcollection.azure_rm_iotdevice_info
azure_rm_iotdevicemodule:
redirect: azure.azcollection.azure_rm_iotdevicemodule
azure_rm_iothub:
redirect: azure.azcollection.azure_rm_iothub
azure_rm_iothub_info:
redirect: azure.azcollection.azure_rm_iothub_info
azure_rm_iothubconsumergroup:
redirect: azure.azcollection.azure_rm_iothubconsumergroup
azure_rm_loadbalancer:
redirect: azure.azcollection.azure_rm_loadbalancer
azure_rm_loadbalancer_info:
redirect: azure.azcollection.azure_rm_loadbalancer_info
azure_rm_lock:
redirect: azure.azcollection.azure_rm_lock
azure_rm_lock_info:
redirect: azure.azcollection.azure_rm_lock_info
azure_rm_loganalyticsworkspace:
redirect: azure.azcollection.azure_rm_loganalyticsworkspace
azure_rm_loganalyticsworkspace_info:
redirect: azure.azcollection.azure_rm_loganalyticsworkspace_info
azure_rm_monitorlogprofile:
redirect: azure.azcollection.azure_rm_monitorlogprofile
azure_rm_rediscache:
redirect: azure.azcollection.azure_rm_rediscache
azure_rm_rediscache_info:
redirect: azure.azcollection.azure_rm_rediscache_info
azure_rm_rediscachefirewallrule:
redirect: azure.azcollection.azure_rm_rediscachefirewallrule
azure_rm_roleassignment:
redirect: azure.azcollection.azure_rm_roleassignment
azure_rm_roleassignment_info:
redirect: azure.azcollection.azure_rm_roleassignment_info
azure_rm_roledefinition:
redirect: azure.azcollection.azure_rm_roledefinition
azure_rm_roledefinition_info:
redirect: azure.azcollection.azure_rm_roledefinition_info
azure_rm_route:
redirect: azure.azcollection.azure_rm_route
azure_rm_routetable:
redirect: azure.azcollection.azure_rm_routetable
azure_rm_routetable_info:
redirect: azure.azcollection.azure_rm_routetable_info
azure_rm_servicebus:
redirect: azure.azcollection.azure_rm_servicebus
azure_rm_servicebus_info:
redirect: azure.azcollection.azure_rm_servicebus_info
azure_rm_servicebusqueue:
redirect: azure.azcollection.azure_rm_servicebusqueue
azure_rm_servicebussaspolicy:
redirect: azure.azcollection.azure_rm_servicebussaspolicy
azure_rm_servicebustopic:
redirect: azure.azcollection.azure_rm_servicebustopic
azure_rm_servicebustopicsubscription:
redirect: azure.azcollection.azure_rm_servicebustopicsubscription
azure_rm_trafficmanagerendpoint:
redirect: azure.azcollection.azure_rm_trafficmanagerendpoint
azure_rm_trafficmanagerendpoint_info:
redirect: azure.azcollection.azure_rm_trafficmanagerendpoint_info
azure_rm_trafficmanagerprofile:
redirect: azure.azcollection.azure_rm_trafficmanagerprofile
azure_rm_trafficmanagerprofile_info:
redirect: azure.azcollection.azure_rm_trafficmanagerprofile_info
azure_rm_virtualnetworkgateway:
redirect: azure.azcollection.azure_rm_virtualnetworkgateway
azure_rm_virtualnetworkpeering:
redirect: azure.azcollection.azure_rm_virtualnetworkpeering
azure_rm_virtualnetworkpeering_info:
redirect: azure.azcollection.azure_rm_virtualnetworkpeering_info
azure_rm_cosmosdbaccount:
redirect: azure.azcollection.azure_rm_cosmosdbaccount
azure_rm_cosmosdbaccount_info:
redirect: azure.azcollection.azure_rm_cosmosdbaccount_info
azure_rm_devtestlab:
redirect: azure.azcollection.azure_rm_devtestlab
azure_rm_devtestlab_info:
redirect: azure.azcollection.azure_rm_devtestlab_info
azure_rm_devtestlabarmtemplate_info:
redirect: azure.azcollection.azure_rm_devtestlabarmtemplate_info
azure_rm_devtestlabartifact_info:
redirect: azure.azcollection.azure_rm_devtestlabartifact_info
azure_rm_devtestlabartifactsource:
redirect: azure.azcollection.azure_rm_devtestlabartifactsource
azure_rm_devtestlabartifactsource_info:
redirect: azure.azcollection.azure_rm_devtestlabartifactsource_info
azure_rm_devtestlabcustomimage:
redirect: azure.azcollection.azure_rm_devtestlabcustomimage
azure_rm_devtestlabcustomimage_info:
redirect: azure.azcollection.azure_rm_devtestlabcustomimage_info
azure_rm_devtestlabenvironment:
redirect: azure.azcollection.azure_rm_devtestlabenvironment
azure_rm_devtestlabenvironment_info:
redirect: azure.azcollection.azure_rm_devtestlabenvironment_info
azure_rm_devtestlabpolicy:
redirect: azure.azcollection.azure_rm_devtestlabpolicy
azure_rm_devtestlabpolicy_info:
redirect: azure.azcollection.azure_rm_devtestlabpolicy_info
azure_rm_devtestlabschedule:
redirect: azure.azcollection.azure_rm_devtestlabschedule
azure_rm_devtestlabschedule_info:
redirect: azure.azcollection.azure_rm_devtestlabschedule_info
azure_rm_devtestlabvirtualmachine:
redirect: azure.azcollection.azure_rm_devtestlabvirtualmachine
azure_rm_devtestlabvirtualmachine_info:
redirect: azure.azcollection.azure_rm_devtestlabvirtualmachine_info
azure_rm_devtestlabvirtualnetwork:
redirect: azure.azcollection.azure_rm_devtestlabvirtualnetwork
azure_rm_devtestlabvirtualnetwork_info:
redirect: azure.azcollection.azure_rm_devtestlabvirtualnetwork_info
azure_rm_hdinsightcluster:
redirect: azure.azcollection.azure_rm_hdinsightcluster
azure_rm_hdinsightcluster_info:
redirect: azure.azcollection.azure_rm_hdinsightcluster_info
azure_rm_mariadbconfiguration:
redirect: azure.azcollection.azure_rm_mariadbconfiguration
azure_rm_mariadbconfiguration_info:
redirect: azure.azcollection.azure_rm_mariadbconfiguration_info
azure_rm_mariadbdatabase:
redirect: azure.azcollection.azure_rm_mariadbdatabase
azure_rm_mariadbdatabase_info:
redirect: azure.azcollection.azure_rm_mariadbdatabase_info
azure_rm_mariadbfirewallrule:
redirect: azure.azcollection.azure_rm_mariadbfirewallrule
azure_rm_mariadbfirewallrule_info:
redirect: azure.azcollection.azure_rm_mariadbfirewallrule_info
azure_rm_mariadbserver:
redirect: azure.azcollection.azure_rm_mariadbserver
azure_rm_mariadbserver_info:
redirect: azure.azcollection.azure_rm_mariadbserver_info
azure_rm_mysqlconfiguration:
redirect: azure.azcollection.azure_rm_mysqlconfiguration
azure_rm_mysqlconfiguration_info:
redirect: azure.azcollection.azure_rm_mysqlconfiguration_info
azure_rm_mysqldatabase:
redirect: azure.azcollection.azure_rm_mysqldatabase
azure_rm_mysqldatabase_info:
redirect: azure.azcollection.azure_rm_mysqldatabase_info
azure_rm_mysqlfirewallrule:
redirect: azure.azcollection.azure_rm_mysqlfirewallrule
azure_rm_mysqlfirewallrule_info:
redirect: azure.azcollection.azure_rm_mysqlfirewallrule_info
azure_rm_mysqlserver:
redirect: azure.azcollection.azure_rm_mysqlserver
azure_rm_mysqlserver_info:
redirect: azure.azcollection.azure_rm_mysqlserver_info
azure_rm_postgresqlconfiguration:
redirect: azure.azcollection.azure_rm_postgresqlconfiguration
azure_rm_postgresqlconfiguration_info:
redirect: azure.azcollection.azure_rm_postgresqlconfiguration_info
azure_rm_postgresqldatabase:
redirect: azure.azcollection.azure_rm_postgresqldatabase
azure_rm_postgresqldatabase_info:
redirect: azure.azcollection.azure_rm_postgresqldatabase_info
azure_rm_postgresqlfirewallrule:
redirect: azure.azcollection.azure_rm_postgresqlfirewallrule
azure_rm_postgresqlfirewallrule_info:
redirect: azure.azcollection.azure_rm_postgresqlfirewallrule_info
azure_rm_postgresqlserver:
redirect: azure.azcollection.azure_rm_postgresqlserver
azure_rm_postgresqlserver_info:
redirect: azure.azcollection.azure_rm_postgresqlserver_info
azure_rm_sqldatabase:
redirect: azure.azcollection.azure_rm_sqldatabase
azure_rm_sqldatabase_info:
redirect: azure.azcollection.azure_rm_sqldatabase_info
azure_rm_sqlfirewallrule:
redirect: azure.azcollection.azure_rm_sqlfirewallrule
azure_rm_sqlfirewallrule_info:
redirect: azure.azcollection.azure_rm_sqlfirewallrule_info
azure_rm_sqlserver:
redirect: azure.azcollection.azure_rm_sqlserver
azure_rm_sqlserver_info:
redirect: azure.azcollection.azure_rm_sqlserver_info
openvswitch_port:
redirect: openvswitch.openvswitch.openvswitch_port
openvswitch_db:
redirect: openvswitch.openvswitch.openvswitch_db
openvswitch_bridge:
redirect: openvswitch.openvswitch.openvswitch_bridge
vyos_ospfv2:
redirect: vyos.vyos.vyos_ospfv2
vyos_l3_interface:
redirect: vyos.vyos.vyos_l3_interface
vyos_banner:
redirect: vyos.vyos.vyos_banner
vyos_firewall_rules:
redirect: vyos.vyos.vyos_firewall_rules
vyos_static_route:
redirect: vyos.vyos.vyos_static_route
vyos_lldp_interface:
redirect: vyos.vyos.vyos_lldp_interface
vyos_vlan:
redirect: vyos.vyos.vyos_vlan
vyos_user:
redirect: vyos.vyos.vyos_user
vyos_firewall_interfaces:
redirect: vyos.vyos.vyos_firewall_interfaces
vyos_interface:
redirect: vyos.vyos.vyos_interface
vyos_firewall_global:
redirect: vyos.vyos.vyos_firewall_global
vyos_config:
redirect: vyos.vyos.vyos_config
vyos_facts:
redirect: vyos.vyos.vyos_facts
vyos_linkagg:
redirect: vyos.vyos.vyos_linkagg
vyos_ping:
redirect: vyos.vyos.vyos_ping
vyos_lag_interfaces:
redirect: vyos.vyos.vyos_lag_interfaces
vyos_lldp:
redirect: vyos.vyos.vyos_lldp
vyos_lldp_global:
redirect: vyos.vyos.vyos_lldp_global
vyos_l3_interfaces:
redirect: vyos.vyos.vyos_l3_interfaces
vyos_lldp_interfaces:
redirect: vyos.vyos.vyos_lldp_interfaces
vyos_interfaces:
redirect: vyos.vyos.vyos_interfaces
vyos_logging:
redirect: vyos.vyos.vyos_logging
vyos_static_routes:
redirect: vyos.vyos.vyos_static_routes
vyos_command:
redirect: vyos.vyos.vyos_command
vyos_system:
redirect: vyos.vyos.vyos_system
cpm_plugconfig:
redirect: wti.remote.cpm_plugconfig
cpm_plugcontrol:
redirect: wti.remote.cpm_plugcontrol
cpm_serial_port_config:
redirect: wti.remote.cpm_serial_port_config
cpm_serial_port_info:
redirect: wti.remote.cpm_serial_port_info
cpm_user:
redirect: wti.remote.cpm_user
module_utils:
# test entries
formerly_core:
redirect: ansible_collections.testns.testcoll.plugins.module_utils.base
sub1.sub2.formerly_core:
redirect: ansible_collections.testns.testcoll.plugins.module_utils.base
# real
acme:
redirect: community.crypto.acme
alicloud_ecs:
redirect: community.general.alicloud_ecs
ansible_tower:
redirect: awx.awx.ansible_tower
aws.batch:
redirect: amazon.aws.batch
aws.cloudfront_facts:
redirect: amazon.aws.cloudfront_facts
aws.core:
redirect: amazon.aws.core
aws.direct_connect:
redirect: amazon.aws.direct_connect
aws.elb_utils:
redirect: amazon.aws.elb_utils
aws.elbv2:
redirect: amazon.aws.elbv2
aws.iam:
redirect: amazon.aws.iam
aws.rds:
redirect: amazon.aws.rds
aws.s3:
redirect: amazon.aws.s3
aws.urls:
redirect: amazon.aws.urls
aws.waf:
redirect: amazon.aws.waf
aws.waiters:
redirect: amazon.aws.waiters
azure_rm_common:
redirect: azure.azcollection.azure_rm_common
azure_rm_common_ext:
redirect: azure.azcollection.azure_rm_common_ext
azure_rm_common_rest:
redirect: azure.azcollection.azure_rm_common_rest
cloud:
redirect: community.general.cloud
cloudscale:
redirect: cloudscale_ch.cloud.api
cloudstack:
redirect: ngine_io.cloudstack.cloudstack
compat.ipaddress:
redirect: ansible.netcommon.compat.ipaddress
crypto:
redirect: community.crypto.crypto
database:
redirect: community.general.database
digital_ocean:
redirect: community.digitalocean.digital_ocean
dimensiondata:
redirect: community.general.dimensiondata
docker:
redirect: community.docker.common
docker.common:
redirect: community.docker.common
docker.swarm:
redirect: community.docker.swarm
ec2:
redirect: amazon.aws.ec2
ecs:
redirect: community.crypto.ecs
ecs.api:
redirect: community.crypto.ecs.api
exoscale:
redirect: ngine_io.exoscale.exoscale
f5_utils:
tombstone:
removal_date: "2019-11-06"
firewalld:
redirect: ansible.posix.firewalld
gcdns:
redirect: community.google.gcdns
gce:
redirect: community.google.gce
gcp:
redirect: community.google.gcp
gcp_utils:
redirect: google.cloud.gcp_utils
gitlab:
redirect: community.general.gitlab
hcloud:
redirect: hetzner.hcloud.hcloud
heroku:
redirect: community.general.heroku
hetzner:
redirect: community.hrobot.robot
hwc_utils:
redirect: community.general.hwc_utils
ibm_sa_utils:
redirect: community.general.ibm_sa_utils
identity:
redirect: community.general.identity
identity.keycloak:
redirect: community.general.identity.keycloak
identity.keycloak.keycloak:
redirect: community.general.identity.keycloak.keycloak
infinibox:
redirect: infinidat.infinibox.infinibox
influxdb:
redirect: community.general.influxdb
ipa:
redirect: community.general.ipa
ismount:
redirect: ansible.posix.mount
k8s.common:
redirect: kubernetes.core.common
k8s.raw:
redirect: kubernetes.core.raw
k8s.scale:
redirect: kubernetes.core.scale
known_hosts:
redirect: community.general.known_hosts
kubevirt:
redirect: community.kubevirt.kubevirt
ldap:
redirect: community.general.ldap
linode:
redirect: community.general.linode
lxd:
redirect: community.general.lxd
manageiq:
redirect: community.general.manageiq
memset:
redirect: community.general.memset
mysql:
redirect: community.mysql.mysql
net_tools.netbox.netbox_utils:
redirect: netbox.netbox.netbox_utils
net_tools.nios:
redirect: community.general.net_tools.nios
net_tools.nios.api:
redirect: community.general.net_tools.nios.api
netapp:
redirect: netapp.ontap.netapp
netapp_elementsw_module:
redirect: netapp.ontap.netapp_elementsw_module
netapp_module:
redirect: netapp.ontap.netapp_module
network.a10.a10:
redirect: community.network.network.a10.a10
network.aci.aci:
redirect: cisco.aci.aci
network.aci.mso:
redirect: cisco.mso.mso
network.aireos.aireos:
redirect: community.network.network.aireos.aireos
network.aos.aos:
redirect: community.network.network.aos.aos
network.aruba.aruba:
redirect: community.network.network.aruba.aruba
network.asa.asa:
redirect: cisco.asa.network.asa.asa
network.avi.ansible_utils:
redirect: community.network.network.avi.ansible_utils
network.avi.avi:
redirect: community.network.network.avi.avi
network.avi.avi_api:
redirect: community.network.network.avi.avi_api
network.bigswitch.bigswitch:
redirect: community.network.network.bigswitch.bigswitch
network.checkpoint.checkpoint:
redirect: check_point.mgmt.checkpoint
network.cloudengine.ce:
redirect: community.network.network.cloudengine.ce
network.cnos.cnos:
redirect: community.network.network.cnos.cnos
network.cnos.cnos_devicerules:
redirect: community.network.network.cnos.cnos_devicerules
network.cnos.cnos_errorcodes:
redirect: community.network.network.cnos.cnos_errorcodes
network.common.cfg.base:
redirect: ansible.netcommon.network.common.cfg.base
network.common.config:
redirect: ansible.netcommon.network.common.config
network.common.facts.facts:
redirect: ansible.netcommon.network.common.facts.facts
network.common.netconf:
redirect: ansible.netcommon.network.common.netconf
network.common.network:
redirect: ansible.netcommon.network.common.network
network.common.parsing:
redirect: ansible.netcommon.network.common.parsing
network.common.utils:
redirect: ansible.netcommon.network.common.utils
network.dellos10.dellos10:
redirect: dellemc.os10.network.os10
network.dellos9.dellos9:
redirect: dellemc.os9.network.os9
network.dellos6.dellos6:
redirect: dellemc.os6.network.os6
network.edgeos.edgeos:
redirect: community.network.network.edgeos.edgeos
network.edgeswitch.edgeswitch:
redirect: community.network.network.edgeswitch.edgeswitch
network.edgeswitch.edgeswitch_interface:
redirect: community.network.network.edgeswitch.edgeswitch_interface
network.enos.enos:
redirect: community.network.network.enos.enos
network.eos.argspec.facts:
redirect: arista.eos.network.eos.argspec.facts
network.eos.argspec.facts.facts:
redirect: arista.eos.network.eos.argspec.facts.facts
network.eos.argspec.interfaces:
redirect: arista.eos.network.eos.argspec.interfaces
network.eos.argspec.interfaces.interfaces:
redirect: arista.eos.network.eos.argspec.interfaces.interfaces
network.eos.argspec.l2_interfaces:
redirect: arista.eos.network.eos.argspec.l2_interfaces
network.eos.argspec.l2_interfaces.l2_interfaces:
redirect: arista.eos.network.eos.argspec.l2_interfaces.l2_interfaces
network.eos.argspec.l3_interfaces:
redirect: arista.eos.network.eos.argspec.l3_interfaces
network.eos.argspec.l3_interfaces.l3_interfaces:
redirect: arista.eos.network.eos.argspec.l3_interfaces.l3_interfaces
network.eos.argspec.lacp:
redirect: arista.eos.network.eos.argspec.lacp
network.eos.argspec.lacp.lacp:
redirect: arista.eos.network.eos.argspec.lacp.lacp
network.eos.argspec.lacp_interfaces:
redirect: arista.eos.network.eos.argspec.lacp_interfaces
network.eos.argspec.lacp_interfaces.lacp_interfaces:
redirect: arista.eos.network.eos.argspec.lacp_interfaces.lacp_interfaces
network.eos.argspec.lag_interfaces:
redirect: arista.eos.network.eos.argspec.lag_interfaces
network.eos.argspec.lag_interfaces.lag_interfaces:
redirect: arista.eos.network.eos.argspec.lag_interfaces.lag_interfaces
network.eos.argspec.lldp_global:
redirect: arista.eos.network.eos.argspec.lldp_global
network.eos.argspec.lldp_global.lldp_global:
redirect: arista.eos.network.eos.argspec.lldp_global.lldp_global
network.eos.argspec.lldp_interfaces:
redirect: arista.eos.network.eos.argspec.lldp_interfaces
network.eos.argspec.lldp_interfaces.lldp_interfaces:
redirect: arista.eos.network.eos.argspec.lldp_interfaces.lldp_interfaces
network.eos.argspec.vlans:
redirect: arista.eos.network.eos.argspec.vlans
network.eos.argspec.vlans.vlans:
redirect: arista.eos.network.eos.argspec.vlans.vlans
network.eos.config:
redirect: arista.eos.network.eos.config
network.eos.config.interfaces:
redirect: arista.eos.network.eos.config.interfaces
network.eos.config.interfaces.interfaces:
redirect: arista.eos.network.eos.config.interfaces.interfaces
network.eos.config.l2_interfaces:
redirect: arista.eos.network.eos.config.l2_interfaces
network.eos.config.l2_interfaces.l2_interfaces:
redirect: arista.eos.network.eos.config.l2_interfaces.l2_interfaces
network.eos.config.l3_interfaces:
redirect: arista.eos.network.eos.config.l3_interfaces
network.eos.config.l3_interfaces.l3_interfaces:
redirect: arista.eos.network.eos.config.l3_interfaces.l3_interfaces
network.eos.config.lacp:
redirect: arista.eos.network.eos.config.lacp
network.eos.config.lacp.lacp:
redirect: arista.eos.network.eos.config.lacp.lacp
network.eos.config.lacp_interfaces:
redirect: arista.eos.network.eos.config.lacp_interfaces
network.eos.config.lacp_interfaces.lacp_interfaces:
redirect: arista.eos.network.eos.config.lacp_interfaces.lacp_interfaces
network.eos.config.lag_interfaces:
redirect: arista.eos.network.eos.config.lag_interfaces
network.eos.config.lag_interfaces.lag_interfaces:
redirect: arista.eos.network.eos.config.lag_interfaces.lag_interfaces
network.eos.config.lldp_global:
redirect: arista.eos.network.eos.config.lldp_global
network.eos.config.lldp_global.lldp_global:
redirect: arista.eos.network.eos.config.lldp_global.lldp_global
network.eos.config.lldp_interfaces:
redirect: arista.eos.network.eos.config.lldp_interfaces
network.eos.config.lldp_interfaces.lldp_interfaces:
redirect: arista.eos.network.eos.config.lldp_interfaces.lldp_interfaces
network.eos.config.vlans:
redirect: arista.eos.network.eos.config.vlans
network.eos.config.vlans.vlans:
redirect: arista.eos.network.eos.config.vlans.vlans
network.eos.eos:
redirect: arista.eos.network.eos.eos
network.eos.facts:
redirect: arista.eos.network.eos.facts
network.eos.facts.facts:
redirect: arista.eos.network.eos.facts.facts
network.eos.facts.interfaces:
redirect: arista.eos.network.eos.facts.interfaces
network.eos.facts.interfaces.interfaces:
redirect: arista.eos.network.eos.facts.interfaces.interfaces
network.eos.facts.l2_interfaces:
redirect: arista.eos.network.eos.facts.l2_interfaces
network.eos.facts.l2_interfaces.l2_interfaces:
redirect: arista.eos.network.eos.facts.l2_interfaces.l2_interfaces
network.eos.facts.l3_interfaces:
redirect: arista.eos.network.eos.facts.l3_interfaces
network.eos.facts.l3_interfaces.l3_interfaces:
redirect: arista.eos.network.eos.facts.l3_interfaces.l3_interfaces
network.eos.facts.lacp:
redirect: arista.eos.network.eos.facts.lacp
network.eos.facts.lacp.lacp:
redirect: arista.eos.network.eos.facts.lacp.lacp
network.eos.facts.lacp_interfaces:
redirect: arista.eos.network.eos.facts.lacp_interfaces
network.eos.facts.lacp_interfaces.lacp_interfaces:
redirect: arista.eos.network.eos.facts.lacp_interfaces.lacp_interfaces
network.eos.facts.lag_interfaces:
redirect: arista.eos.network.eos.facts.lag_interfaces
network.eos.facts.lag_interfaces.lag_interfaces:
redirect: arista.eos.network.eos.facts.lag_interfaces.lag_interfaces
network.eos.facts.legacy:
redirect: arista.eos.network.eos.facts.legacy
network.eos.facts.legacy.base:
redirect: arista.eos.network.eos.facts.legacy.base
network.eos.facts.lldp_global:
redirect: arista.eos.network.eos.facts.lldp_global
network.eos.facts.lldp_global.lldp_global:
redirect: arista.eos.network.eos.facts.lldp_global.lldp_global
network.eos.facts.lldp_interfaces:
redirect: arista.eos.network.eos.facts.lldp_interfaces
network.eos.facts.lldp_interfaces.lldp_interfaces:
redirect: arista.eos.network.eos.facts.lldp_interfaces.lldp_interfaces
network.eos.facts.vlans:
redirect: arista.eos.network.eos.facts.vlans
network.eos.facts.vlans.vlans:
redirect: arista.eos.network.eos.facts.vlans.vlans
network.eos.providers:
redirect: arista.eos.network.eos.providers
network.eos.providers.cli:
redirect: arista.eos.network.eos.providers.cli
network.eos.providers.cli.config:
redirect: arista.eos.network.eos.providers.cli.config
network.eos.providers.cli.config.bgp:
redirect: arista.eos.network.eos.providers.cli.config.bgp
network.eos.providers.cli.config.bgp.address_family:
redirect: arista.eos.network.eos.providers.cli.config.bgp.address_family
network.eos.providers.cli.config.bgp.neighbors:
redirect: arista.eos.network.eos.providers.cli.config.bgp.neighbors
network.eos.providers.cli.config.bgp.process:
redirect: arista.eos.network.eos.providers.cli.config.bgp.process
network.eos.providers.module:
redirect: arista.eos.network.eos.providers.module
network.eos.providers.providers:
redirect: arista.eos.network.eos.providers.providers
network.eos.utils:
redirect: arista.eos.network.eos.utils
network.eos.utils.utils:
redirect: arista.eos.network.eos.utils.utils
network.eric_eccli.eric_eccli:
redirect: community.network.network.eric_eccli.eric_eccli
network.exos.argspec.facts.facts:
redirect: community.network.network.exos.argspec.facts.facts
network.exos.argspec.lldp_global:
redirect: community.network.network.exos.argspec.lldp_global
network.exos.argspec.lldp_global.lldp_global:
redirect: community.network.network.exos.argspec.lldp_global.lldp_global
network.exos.config.lldp_global:
redirect: community.network.network.exos.config.lldp_global
network.exos.config.lldp_global.lldp_global:
redirect: community.network.network.exos.config.lldp_global.lldp_global
network.exos.exos:
redirect: community.network.network.exos.exos
network.exos.facts.facts:
redirect: community.network.network.exos.facts.facts
network.exos.facts.legacy:
redirect: community.network.network.exos.facts.legacy
network.exos.facts.legacy.base:
redirect: community.network.network.exos.facts.legacy.base
network.exos.facts.lldp_global:
redirect: community.network.network.exos.facts.lldp_global
network.exos.facts.lldp_global.lldp_global:
redirect: community.network.network.exos.facts.lldp_global.lldp_global
network.exos.utils.utils:
redirect: community.network.network.exos.utils.utils
network.f5.bigip:
redirect: f5networks.f5_modules.bigip
network.f5.bigiq:
redirect: f5networks.f5_modules.bigiq
network.f5.common:
redirect: f5networks.f5_modules.common
network.f5.compare:
redirect: f5networks.f5_modules.compare
network.f5.icontrol:
redirect: f5networks.f5_modules.icontrol
network.f5.ipaddress:
redirect: f5networks.f5_modules.ipaddress
# FIXME: missing
#network.f5.iworkflow:
# redirect: f5networks.f5_modules.iworkflow
#network.f5.legacy:
# redirect: f5networks.f5_modules.legacy
network.f5.urls:
redirect: f5networks.f5_modules.urls
network.fortianalyzer.common:
redirect: community.fortios.fortianalyzer.common
network.fortianalyzer.fortianalyzer:
redirect: community.fortios.fortianalyzer.fortianalyzer
network.fortimanager.common:
redirect: fortinet.fortimanager.common
network.fortimanager.fortimanager:
redirect: fortinet.fortimanager.fortimanager
network.fortios.argspec:
redirect: fortinet.fortios.fortios.argspec
network.fortios.argspec.facts:
redirect: fortinet.fortios.fortios.argspec.facts
network.fortios.argspec.facts.facts:
redirect: fortinet.fortios.fortios.argspec.facts.facts
network.fortios.argspec.system:
redirect: fortinet.fortios.fortios.argspec.system
network.fortios.argspec.system.system:
redirect: fortinet.fortios.fortios.argspec.system.system
network.fortios.facts:
redirect: fortinet.fortios.fortios.facts
network.fortios.facts.facts:
redirect: fortinet.fortios.fortios.facts.facts
network.fortios.facts.system:
redirect: fortinet.fortios.fortios.facts.system
network.fortios.facts.system.system:
redirect: fortinet.fortios.fortios.facts.system.system
network.fortios.fortios:
redirect: fortinet.fortios.fortios.fortios
network.frr:
redirect: frr.frr.network.frr
network.frr.frr:
redirect: frr.frr.network.frr.frr
network.frr.providers:
redirect: frr.frr.network.frr.providers
network.frr.providers.cli:
redirect: frr.frr.network.frr.providers.cli
network.frr.providers.cli.config:
redirect: frr.frr.network.frr.providers.cli.config
network.frr.providers.cli.config.base:
redirect: frr.frr.network.frr.providers.cli.config.base
network.frr.providers.cli.config.bgp:
redirect: frr.frr.network.frr.providers.cli.config.bgp
network.frr.providers.cli.config.bgp.address_family:
redirect: frr.frr.network.frr.providers.cli.config.bgp.address_family
network.frr.providers.cli.config.bgp.neighbors:
redirect: frr.frr.network.frr.providers.cli.config.bgp.neighbors
network.frr.providers.cli.config.bgp.process:
redirect: frr.frr.network.frr.providers.cli.config.bgp.process
network.frr.providers.module:
redirect: frr.frr.network.frr.providers.module
network.frr.providers.providers:
redirect: frr.frr.network.frr.providers.providers
network.ftd:
redirect: community.network.network.ftd
network.ftd.common:
redirect: community.network.network.ftd.common
network.ftd.configuration:
redirect: community.network.network.ftd.configuration
network.ftd.device:
redirect: community.network.network.ftd.device
network.ftd.fdm_swagger_client:
redirect: community.network.network.ftd.fdm_swagger_client
network.ftd.operation:
redirect: community.network.network.ftd.operation
network.icx:
redirect: community.network.network.icx
network.icx.icx:
redirect: community.network.network.icx.icx
network.ingate:
redirect: community.network.network.ingate
network.ingate.common:
redirect: community.network.network.ingate.common
network.ios:
redirect: cisco.ios.network.ios
network.ios.argspec:
redirect: cisco.ios.network.ios.argspec
network.ios.argspec.facts:
redirect: cisco.ios.network.ios.argspec.facts
network.ios.argspec.facts.facts:
redirect: cisco.ios.network.ios.argspec.facts.facts
network.ios.argspec.interfaces:
redirect: cisco.ios.network.ios.argspec.interfaces
network.ios.argspec.interfaces.interfaces:
redirect: cisco.ios.network.ios.argspec.interfaces.interfaces
network.ios.argspec.l2_interfaces:
redirect: cisco.ios.network.ios.argspec.l2_interfaces
network.ios.argspec.l2_interfaces.l2_interfaces:
redirect: cisco.ios.network.ios.argspec.l2_interfaces.l2_interfaces
network.ios.argspec.l3_interfaces:
redirect: cisco.ios.network.ios.argspec.l3_interfaces
network.ios.argspec.l3_interfaces.l3_interfaces:
redirect: cisco.ios.network.ios.argspec.l3_interfaces.l3_interfaces
network.ios.argspec.lacp:
redirect: cisco.ios.network.ios.argspec.lacp
network.ios.argspec.lacp.lacp:
redirect: cisco.ios.network.ios.argspec.lacp.lacp
network.ios.argspec.lacp_interfaces:
redirect: cisco.ios.network.ios.argspec.lacp_interfaces
network.ios.argspec.lacp_interfaces.lacp_interfaces:
redirect: cisco.ios.network.ios.argspec.lacp_interfaces.lacp_interfaces
network.ios.argspec.lag_interfaces:
redirect: cisco.ios.network.ios.argspec.lag_interfaces
network.ios.argspec.lag_interfaces.lag_interfaces:
redirect: cisco.ios.network.ios.argspec.lag_interfaces.lag_interfaces
network.ios.argspec.lldp_global:
redirect: cisco.ios.network.ios.argspec.lldp_global
network.ios.argspec.lldp_global.lldp_global:
redirect: cisco.ios.network.ios.argspec.lldp_global.lldp_global
network.ios.argspec.lldp_interfaces:
redirect: cisco.ios.network.ios.argspec.lldp_interfaces
network.ios.argspec.lldp_interfaces.lldp_interfaces:
redirect: cisco.ios.network.ios.argspec.lldp_interfaces.lldp_interfaces
network.ios.argspec.vlans:
redirect: cisco.ios.network.ios.argspec.vlans
network.ios.argspec.vlans.vlans:
redirect: cisco.ios.network.ios.argspec.vlans.vlans
network.ios.config:
redirect: cisco.ios.network.ios.config
network.ios.config.interfaces:
redirect: cisco.ios.network.ios.config.interfaces
network.ios.config.interfaces.interfaces:
redirect: cisco.ios.network.ios.config.interfaces.interfaces
network.ios.config.l2_interfaces:
redirect: cisco.ios.network.ios.config.l2_interfaces
network.ios.config.l2_interfaces.l2_interfaces:
redirect: cisco.ios.network.ios.config.l2_interfaces.l2_interfaces
network.ios.config.l3_interfaces:
redirect: cisco.ios.network.ios.config.l3_interfaces
network.ios.config.l3_interfaces.l3_interfaces:
redirect: cisco.ios.network.ios.config.l3_interfaces.l3_interfaces
network.ios.config.lacp:
redirect: cisco.ios.network.ios.config.lacp
network.ios.config.lacp.lacp:
redirect: cisco.ios.network.ios.config.lacp.lacp
network.ios.config.lacp_interfaces:
redirect: cisco.ios.network.ios.config.lacp_interfaces
network.ios.config.lacp_interfaces.lacp_interfaces:
redirect: cisco.ios.network.ios.config.lacp_interfaces.lacp_interfaces
network.ios.config.lag_interfaces:
redirect: cisco.ios.network.ios.config.lag_interfaces
network.ios.config.lag_interfaces.lag_interfaces:
redirect: cisco.ios.network.ios.config.lag_interfaces.lag_interfaces
network.ios.config.lldp_global:
redirect: cisco.ios.network.ios.config.lldp_global
network.ios.config.lldp_global.lldp_global:
redirect: cisco.ios.network.ios.config.lldp_global.lldp_global
network.ios.config.lldp_interfaces:
redirect: cisco.ios.network.ios.config.lldp_interfaces
network.ios.config.lldp_interfaces.lldp_interfaces:
redirect: cisco.ios.network.ios.config.lldp_interfaces.lldp_interfaces
network.ios.config.vlans:
redirect: cisco.ios.network.ios.config.vlans
network.ios.config.vlans.vlans:
redirect: cisco.ios.network.ios.config.vlans.vlans
network.ios.facts:
redirect: cisco.ios.network.ios.facts
network.ios.facts.facts:
redirect: cisco.ios.network.ios.facts.facts
network.ios.facts.interfaces:
redirect: cisco.ios.network.ios.facts.interfaces
network.ios.facts.interfaces.interfaces:
redirect: cisco.ios.network.ios.facts.interfaces.interfaces
network.ios.facts.l2_interfaces:
redirect: cisco.ios.network.ios.facts.l2_interfaces
network.ios.facts.l2_interfaces.l2_interfaces:
redirect: cisco.ios.network.ios.facts.l2_interfaces.l2_interfaces
network.ios.facts.l3_interfaces:
redirect: cisco.ios.network.ios.facts.l3_interfaces
network.ios.facts.l3_interfaces.l3_interfaces:
redirect: cisco.ios.network.ios.facts.l3_interfaces.l3_interfaces
network.ios.facts.lacp:
redirect: cisco.ios.network.ios.facts.lacp
network.ios.facts.lacp.lacp:
redirect: cisco.ios.network.ios.facts.lacp.lacp
network.ios.facts.lacp_interfaces:
redirect: cisco.ios.network.ios.facts.lacp_interfaces
network.ios.facts.lacp_interfaces.lacp_interfaces:
redirect: cisco.ios.network.ios.facts.lacp_interfaces.lacp_interfaces
network.ios.facts.lag_interfaces:
redirect: cisco.ios.network.ios.facts.lag_interfaces
network.ios.facts.lag_interfaces.lag_interfaces:
redirect: cisco.ios.network.ios.facts.lag_interfaces.lag_interfaces
network.ios.facts.legacy:
redirect: cisco.ios.network.ios.facts.legacy
network.ios.facts.legacy.base:
redirect: cisco.ios.network.ios.facts.legacy.base
network.ios.facts.lldp_global:
redirect: cisco.ios.network.ios.facts.lldp_global
network.ios.facts.lldp_global.lldp_global:
redirect: cisco.ios.network.ios.facts.lldp_global.lldp_global
network.ios.facts.lldp_interfaces:
redirect: cisco.ios.network.ios.facts.lldp_interfaces
network.ios.facts.lldp_interfaces.lldp_interfaces:
redirect: cisco.ios.network.ios.facts.lldp_interfaces.lldp_interfaces
network.ios.facts.vlans:
redirect: cisco.ios.network.ios.facts.vlans
network.ios.facts.vlans.vlans:
redirect: cisco.ios.network.ios.facts.vlans.vlans
network.ios.ios:
redirect: cisco.ios.network.ios.ios
network.ios.providers:
redirect: cisco.ios.network.ios.providers
network.ios.providers.cli:
redirect: cisco.ios.network.ios.providers.cli
network.ios.providers.cli.config:
redirect: cisco.ios.network.ios.providers.cli.config
network.ios.providers.cli.config.base:
redirect: cisco.ios.network.ios.providers.cli.config.base
network.ios.providers.cli.config.bgp:
redirect: cisco.ios.network.ios.providers.cli.config.bgp
network.ios.providers.cli.config.bgp.address_family:
redirect: cisco.ios.network.ios.providers.cli.config.bgp.address_family
network.ios.providers.cli.config.bgp.neighbors:
redirect: cisco.ios.network.ios.providers.cli.config.bgp.neighbors
network.ios.providers.cli.config.bgp.process:
redirect: cisco.ios.network.ios.providers.cli.config.bgp.process
network.ios.providers.module:
redirect: cisco.ios.network.ios.providers.module
network.ios.providers.providers:
redirect: cisco.ios.network.ios.providers.providers
network.ios.utils:
redirect: cisco.ios.network.ios.utils
network.ios.utils.utils:
redirect: cisco.ios.network.ios.utils.utils
network.iosxr:
redirect: cisco.iosxr.network.iosxr
network.iosxr.argspec:
redirect: cisco.iosxr.network.iosxr.argspec
network.iosxr.argspec.facts:
redirect: cisco.iosxr.network.iosxr.argspec.facts
network.iosxr.argspec.facts.facts:
redirect: cisco.iosxr.network.iosxr.argspec.facts.facts
network.iosxr.argspec.interfaces:
redirect: cisco.iosxr.network.iosxr.argspec.interfaces
network.iosxr.argspec.interfaces.interfaces:
redirect: cisco.iosxr.network.iosxr.argspec.interfaces.interfaces
network.iosxr.argspec.l2_interfaces:
redirect: cisco.iosxr.network.iosxr.argspec.l2_interfaces
network.iosxr.argspec.l2_interfaces.l2_interfaces:
redirect: cisco.iosxr.network.iosxr.argspec.l2_interfaces.l2_interfaces
network.iosxr.argspec.l3_interfaces:
redirect: cisco.iosxr.network.iosxr.argspec.l3_interfaces
network.iosxr.argspec.l3_interfaces.l3_interfaces:
redirect: cisco.iosxr.network.iosxr.argspec.l3_interfaces.l3_interfaces
network.iosxr.argspec.lacp:
redirect: cisco.iosxr.network.iosxr.argspec.lacp
network.iosxr.argspec.lacp.lacp:
redirect: cisco.iosxr.network.iosxr.argspec.lacp.lacp
network.iosxr.argspec.lacp_interfaces:
redirect: cisco.iosxr.network.iosxr.argspec.lacp_interfaces
network.iosxr.argspec.lacp_interfaces.lacp_interfaces:
redirect: cisco.iosxr.network.iosxr.argspec.lacp_interfaces.lacp_interfaces
network.iosxr.argspec.lag_interfaces:
redirect: cisco.iosxr.network.iosxr.argspec.lag_interfaces
network.iosxr.argspec.lag_interfaces.lag_interfaces:
redirect: cisco.iosxr.network.iosxr.argspec.lag_interfaces.lag_interfaces
network.iosxr.argspec.lldp_global:
redirect: cisco.iosxr.network.iosxr.argspec.lldp_global
network.iosxr.argspec.lldp_global.lldp_global:
redirect: cisco.iosxr.network.iosxr.argspec.lldp_global.lldp_global
network.iosxr.argspec.lldp_interfaces:
redirect: cisco.iosxr.network.iosxr.argspec.lldp_interfaces
network.iosxr.argspec.lldp_interfaces.lldp_interfaces:
redirect: cisco.iosxr.network.iosxr.argspec.lldp_interfaces.lldp_interfaces
network.iosxr.config:
redirect: cisco.iosxr.network.iosxr.config
network.iosxr.config.interfaces:
redirect: cisco.iosxr.network.iosxr.config.interfaces
network.iosxr.config.interfaces.interfaces:
redirect: cisco.iosxr.network.iosxr.config.interfaces.interfaces
network.iosxr.config.l2_interfaces:
redirect: cisco.iosxr.network.iosxr.config.l2_interfaces
network.iosxr.config.l2_interfaces.l2_interfaces:
redirect: cisco.iosxr.network.iosxr.config.l2_interfaces.l2_interfaces
network.iosxr.config.l3_interfaces:
redirect: cisco.iosxr.network.iosxr.config.l3_interfaces
network.iosxr.config.l3_interfaces.l3_interfaces:
redirect: cisco.iosxr.network.iosxr.config.l3_interfaces.l3_interfaces
network.iosxr.config.lacp:
redirect: cisco.iosxr.network.iosxr.config.lacp
network.iosxr.config.lacp.lacp:
redirect: cisco.iosxr.network.iosxr.config.lacp.lacp
network.iosxr.config.lacp_interfaces:
redirect: cisco.iosxr.network.iosxr.config.lacp_interfaces
network.iosxr.config.lacp_interfaces.lacp_interfaces:
redirect: cisco.iosxr.network.iosxr.config.lacp_interfaces.lacp_interfaces
network.iosxr.config.lag_interfaces:
redirect: cisco.iosxr.network.iosxr.config.lag_interfaces
network.iosxr.config.lag_interfaces.lag_interfaces:
redirect: cisco.iosxr.network.iosxr.config.lag_interfaces.lag_interfaces
network.iosxr.config.lldp_global:
redirect: cisco.iosxr.network.iosxr.config.lldp_global
network.iosxr.config.lldp_global.lldp_global:
redirect: cisco.iosxr.network.iosxr.config.lldp_global.lldp_global
network.iosxr.config.lldp_interfaces:
redirect: cisco.iosxr.network.iosxr.config.lldp_interfaces
network.iosxr.config.lldp_interfaces.lldp_interfaces:
redirect: cisco.iosxr.network.iosxr.config.lldp_interfaces.lldp_interfaces
network.iosxr.facts:
redirect: cisco.iosxr.network.iosxr.facts
network.iosxr.facts.facts:
redirect: cisco.iosxr.network.iosxr.facts.facts
network.iosxr.facts.interfaces:
redirect: cisco.iosxr.network.iosxr.facts.interfaces
network.iosxr.facts.interfaces.interfaces:
redirect: cisco.iosxr.network.iosxr.facts.interfaces.interfaces
network.iosxr.facts.l2_interfaces:
redirect: cisco.iosxr.network.iosxr.facts.l2_interfaces
network.iosxr.facts.l2_interfaces.l2_interfaces:
redirect: cisco.iosxr.network.iosxr.facts.l2_interfaces.l2_interfaces
network.iosxr.facts.l3_interfaces:
redirect: cisco.iosxr.network.iosxr.facts.l3_interfaces
network.iosxr.facts.l3_interfaces.l3_interfaces:
redirect: cisco.iosxr.network.iosxr.facts.l3_interfaces.l3_interfaces
network.iosxr.facts.lacp:
redirect: cisco.iosxr.network.iosxr.facts.lacp
network.iosxr.facts.lacp.lacp:
redirect: cisco.iosxr.network.iosxr.facts.lacp.lacp
network.iosxr.facts.lacp_interfaces:
redirect: cisco.iosxr.network.iosxr.facts.lacp_interfaces
network.iosxr.facts.lacp_interfaces.lacp_interfaces:
redirect: cisco.iosxr.network.iosxr.facts.lacp_interfaces.lacp_interfaces
network.iosxr.facts.lag_interfaces:
redirect: cisco.iosxr.network.iosxr.facts.lag_interfaces
network.iosxr.facts.lag_interfaces.lag_interfaces:
redirect: cisco.iosxr.network.iosxr.facts.lag_interfaces.lag_interfaces
network.iosxr.facts.legacy:
redirect: cisco.iosxr.network.iosxr.facts.legacy
network.iosxr.facts.legacy.base:
redirect: cisco.iosxr.network.iosxr.facts.legacy.base
network.iosxr.facts.lldp_global:
redirect: cisco.iosxr.network.iosxr.facts.lldp_global
network.iosxr.facts.lldp_global.lldp_global:
redirect: cisco.iosxr.network.iosxr.facts.lldp_global.lldp_global
network.iosxr.facts.lldp_interfaces:
redirect: cisco.iosxr.network.iosxr.facts.lldp_interfaces
network.iosxr.facts.lldp_interfaces.lldp_interfaces:
redirect: cisco.iosxr.network.iosxr.facts.lldp_interfaces.lldp_interfaces
network.iosxr.iosxr:
redirect: cisco.iosxr.network.iosxr.iosxr
network.iosxr.providers:
redirect: cisco.iosxr.network.iosxr.providers
network.iosxr.providers.cli:
redirect: cisco.iosxr.network.iosxr.providers.cli
network.iosxr.providers.cli.config:
redirect: cisco.iosxr.network.iosxr.providers.cli.config
network.iosxr.providers.cli.config.bgp:
redirect: cisco.iosxr.network.iosxr.providers.cli.config.bgp
network.iosxr.providers.cli.config.bgp.address_family:
redirect: cisco.iosxr.network.iosxr.providers.cli.config.bgp.address_family
network.iosxr.providers.cli.config.bgp.neighbors:
redirect: cisco.iosxr.network.iosxr.providers.cli.config.bgp.neighbors
network.iosxr.providers.cli.config.bgp.process:
redirect: cisco.iosxr.network.iosxr.providers.cli.config.bgp.process
network.iosxr.providers.module:
redirect: cisco.iosxr.network.iosxr.providers.module
network.iosxr.providers.providers:
redirect: cisco.iosxr.network.iosxr.providers.providers
network.iosxr.utils:
redirect: cisco.iosxr.network.iosxr.utils
network.iosxr.utils.utils:
redirect: cisco.iosxr.network.iosxr.utils.utils
network.ironware:
redirect: community.network.network.ironware
network.ironware.ironware:
redirect: community.network.network.ironware.ironware
network.junos:
redirect: junipernetworks.junos.network.junos
network.junos.argspec:
redirect: junipernetworks.junos.network.junos.argspec
network.junos.argspec.facts:
redirect: junipernetworks.junos.network.junos.argspec.facts
network.junos.argspec.facts.facts:
redirect: junipernetworks.junos.network.junos.argspec.facts.facts
network.junos.argspec.interfaces:
redirect: junipernetworks.junos.network.junos.argspec.interfaces
network.junos.argspec.interfaces.interfaces:
redirect: junipernetworks.junos.network.junos.argspec.interfaces.interfaces
network.junos.argspec.l2_interfaces:
redirect: junipernetworks.junos.network.junos.argspec.l2_interfaces
network.junos.argspec.l2_interfaces.l2_interfaces:
redirect: junipernetworks.junos.network.junos.argspec.l2_interfaces.l2_interfaces
network.junos.argspec.l3_interfaces:
redirect: junipernetworks.junos.network.junos.argspec.l3_interfaces
network.junos.argspec.l3_interfaces.l3_interfaces:
redirect: junipernetworks.junos.network.junos.argspec.l3_interfaces.l3_interfaces
network.junos.argspec.lacp:
redirect: junipernetworks.junos.network.junos.argspec.lacp
network.junos.argspec.lacp.lacp:
redirect: junipernetworks.junos.network.junos.argspec.lacp.lacp
network.junos.argspec.lacp_interfaces:
redirect: junipernetworks.junos.network.junos.argspec.lacp_interfaces
network.junos.argspec.lacp_interfaces.lacp_interfaces:
redirect: junipernetworks.junos.network.junos.argspec.lacp_interfaces.lacp_interfaces
network.junos.argspec.lag_interfaces:
redirect: junipernetworks.junos.network.junos.argspec.lag_interfaces
network.junos.argspec.lag_interfaces.lag_interfaces:
redirect: junipernetworks.junos.network.junos.argspec.lag_interfaces.lag_interfaces
network.junos.argspec.lldp_global:
redirect: junipernetworks.junos.network.junos.argspec.lldp_global
network.junos.argspec.lldp_global.lldp_global:
redirect: junipernetworks.junos.network.junos.argspec.lldp_global.lldp_global
network.junos.argspec.lldp_interfaces:
redirect: junipernetworks.junos.network.junos.argspec.lldp_interfaces
network.junos.argspec.lldp_interfaces.lldp_interfaces:
redirect: junipernetworks.junos.network.junos.argspec.lldp_interfaces.lldp_interfaces
network.junos.argspec.vlans:
redirect: junipernetworks.junos.network.junos.argspec.vlans
network.junos.argspec.vlans.vlans:
redirect: junipernetworks.junos.network.junos.argspec.vlans.vlans
network.junos.config:
redirect: junipernetworks.junos.network.junos.config
network.junos.config.interfaces:
redirect: junipernetworks.junos.network.junos.config.interfaces
network.junos.config.interfaces.interfaces:
redirect: junipernetworks.junos.network.junos.config.interfaces.interfaces
network.junos.config.l2_interfaces:
redirect: junipernetworks.junos.network.junos.config.l2_interfaces
network.junos.config.l2_interfaces.l2_interfaces:
redirect: junipernetworks.junos.network.junos.config.l2_interfaces.l2_interfaces
network.junos.config.l3_interfaces:
redirect: junipernetworks.junos.network.junos.config.l3_interfaces
network.junos.config.l3_interfaces.l3_interfaces:
redirect: junipernetworks.junos.network.junos.config.l3_interfaces.l3_interfaces
network.junos.config.lacp:
redirect: junipernetworks.junos.network.junos.config.lacp
network.junos.config.lacp.lacp:
redirect: junipernetworks.junos.network.junos.config.lacp.lacp
network.junos.config.lacp_interfaces:
redirect: junipernetworks.junos.network.junos.config.lacp_interfaces
network.junos.config.lacp_interfaces.lacp_interfaces:
redirect: junipernetworks.junos.network.junos.config.lacp_interfaces.lacp_interfaces
network.junos.config.lag_interfaces:
redirect: junipernetworks.junos.network.junos.config.lag_interfaces
network.junos.config.lag_interfaces.lag_interfaces:
redirect: junipernetworks.junos.network.junos.config.lag_interfaces.lag_interfaces
network.junos.config.lldp_global:
redirect: junipernetworks.junos.network.junos.config.lldp_global
network.junos.config.lldp_global.lldp_global:
redirect: junipernetworks.junos.network.junos.config.lldp_global.lldp_global
network.junos.config.lldp_interfaces:
redirect: junipernetworks.junos.network.junos.config.lldp_interfaces
network.junos.config.lldp_interfaces.lldp_interfaces:
redirect: junipernetworks.junos.network.junos.config.lldp_interfaces.lldp_interfaces
network.junos.config.vlans:
redirect: junipernetworks.junos.network.junos.config.vlans
network.junos.config.vlans.vlans:
redirect: junipernetworks.junos.network.junos.config.vlans.vlans
network.junos.facts:
redirect: junipernetworks.junos.network.junos.facts
network.junos.facts.facts:
redirect: junipernetworks.junos.network.junos.facts.facts
network.junos.facts.interfaces:
redirect: junipernetworks.junos.network.junos.facts.interfaces
network.junos.facts.interfaces.interfaces:
redirect: junipernetworks.junos.network.junos.facts.interfaces.interfaces
network.junos.facts.l2_interfaces:
redirect: junipernetworks.junos.network.junos.facts.l2_interfaces
network.junos.facts.l2_interfaces.l2_interfaces:
redirect: junipernetworks.junos.network.junos.facts.l2_interfaces.l2_interfaces
network.junos.facts.l3_interfaces:
redirect: junipernetworks.junos.network.junos.facts.l3_interfaces
network.junos.facts.l3_interfaces.l3_interfaces:
redirect: junipernetworks.junos.network.junos.facts.l3_interfaces.l3_interfaces
network.junos.facts.lacp:
redirect: junipernetworks.junos.network.junos.facts.lacp
network.junos.facts.lacp.lacp:
redirect: junipernetworks.junos.network.junos.facts.lacp.lacp
network.junos.facts.lacp_interfaces:
redirect: junipernetworks.junos.network.junos.facts.lacp_interfaces
network.junos.facts.lacp_interfaces.lacp_interfaces:
redirect: junipernetworks.junos.network.junos.facts.lacp_interfaces.lacp_interfaces
network.junos.facts.lag_interfaces:
redirect: junipernetworks.junos.network.junos.facts.lag_interfaces
network.junos.facts.lag_interfaces.lag_interfaces:
redirect: junipernetworks.junos.network.junos.facts.lag_interfaces.lag_interfaces
network.junos.facts.legacy:
redirect: junipernetworks.junos.network.junos.facts.legacy
network.junos.facts.legacy.base:
redirect: junipernetworks.junos.network.junos.facts.legacy.base
network.junos.facts.lldp_global:
redirect: junipernetworks.junos.network.junos.facts.lldp_global
network.junos.facts.lldp_global.lldp_global:
redirect: junipernetworks.junos.network.junos.facts.lldp_global.lldp_global
network.junos.facts.lldp_interfaces:
redirect: junipernetworks.junos.network.junos.facts.lldp_interfaces
network.junos.facts.lldp_interfaces.lldp_interfaces:
redirect: junipernetworks.junos.network.junos.facts.lldp_interfaces.lldp_interfaces
network.junos.facts.vlans:
redirect: junipernetworks.junos.network.junos.facts.vlans
network.junos.facts.vlans.vlans:
redirect: junipernetworks.junos.network.junos.facts.vlans.vlans
network.junos.junos:
redirect: junipernetworks.junos.network.junos.junos
network.junos.utils:
redirect: junipernetworks.junos.network.junos.utils
network.junos.utils.utils:
redirect: junipernetworks.junos.network.junos.utils.utils
network.meraki:
redirect: cisco.meraki.network.meraki
network.meraki.meraki:
redirect: cisco.meraki.network.meraki.meraki
network.netconf:
redirect: ansible.netcommon.network.netconf
network.netconf.netconf:
redirect: ansible.netcommon.network.netconf.netconf
network.netscaler:
redirect: community.network.network.netscaler
network.netscaler.netscaler:
redirect: community.network.network.netscaler.netscaler
network.netvisor:
redirect: community.network.network.netvisor
network.netvisor.netvisor:
redirect: community.network.network.netvisor.netvisor
network.netvisor.pn_nvos:
redirect: community.network.network.netvisor.pn_nvos
network.nos:
redirect: community.network.network.nos
network.nos.nos:
redirect: community.network.network.nos.nos
network.nso:
redirect: cisco.nso.nso
network.nso.nso:
redirect: cisco.nso.nso
network.nxos:
redirect: cisco.nxos.network.nxos
network.nxos.argspec:
redirect: cisco.nxos.network.nxos.argspec
network.nxos.argspec.bfd_interfaces:
redirect: cisco.nxos.network.nxos.argspec.bfd_interfaces
network.nxos.argspec.bfd_interfaces.bfd_interfaces:
redirect: cisco.nxos.network.nxos.argspec.bfd_interfaces.bfd_interfaces
network.nxos.argspec.facts:
redirect: cisco.nxos.network.nxos.argspec.facts
network.nxos.argspec.facts.facts:
redirect: cisco.nxos.network.nxos.argspec.facts.facts
network.nxos.argspec.interfaces:
redirect: cisco.nxos.network.nxos.argspec.interfaces
network.nxos.argspec.interfaces.interfaces:
redirect: cisco.nxos.network.nxos.argspec.interfaces.interfaces
network.nxos.argspec.l2_interfaces:
redirect: cisco.nxos.network.nxos.argspec.l2_interfaces
network.nxos.argspec.l2_interfaces.l2_interfaces:
redirect: cisco.nxos.network.nxos.argspec.l2_interfaces.l2_interfaces
network.nxos.argspec.l3_interfaces:
redirect: cisco.nxos.network.nxos.argspec.l3_interfaces
network.nxos.argspec.l3_interfaces.l3_interfaces:
redirect: cisco.nxos.network.nxos.argspec.l3_interfaces.l3_interfaces
network.nxos.argspec.lacp:
redirect: cisco.nxos.network.nxos.argspec.lacp
network.nxos.argspec.lacp.lacp:
redirect: cisco.nxos.network.nxos.argspec.lacp.lacp
network.nxos.argspec.lacp_interfaces:
redirect: cisco.nxos.network.nxos.argspec.lacp_interfaces
network.nxos.argspec.lacp_interfaces.lacp_interfaces:
redirect: cisco.nxos.network.nxos.argspec.lacp_interfaces.lacp_interfaces
network.nxos.argspec.lag_interfaces:
redirect: cisco.nxos.network.nxos.argspec.lag_interfaces
network.nxos.argspec.lag_interfaces.lag_interfaces:
redirect: cisco.nxos.network.nxos.argspec.lag_interfaces.lag_interfaces
network.nxos.argspec.lldp_global:
redirect: cisco.nxos.network.nxos.argspec.lldp_global
network.nxos.argspec.lldp_global.lldp_global:
redirect: cisco.nxos.network.nxos.argspec.lldp_global.lldp_global
network.nxos.argspec.telemetry:
redirect: cisco.nxos.network.nxos.argspec.telemetry
network.nxos.argspec.telemetry.telemetry:
redirect: cisco.nxos.network.nxos.argspec.telemetry.telemetry
network.nxos.argspec.vlans:
redirect: cisco.nxos.network.nxos.argspec.vlans
network.nxos.argspec.vlans.vlans:
redirect: cisco.nxos.network.nxos.argspec.vlans.vlans
network.nxos.cmdref:
redirect: cisco.nxos.network.nxos.cmdref
network.nxos.cmdref.telemetry:
redirect: cisco.nxos.network.nxos.cmdref.telemetry
network.nxos.cmdref.telemetry.telemetry:
redirect: cisco.nxos.network.nxos.cmdref.telemetry.telemetry
network.nxos.config:
redirect: cisco.nxos.network.nxos.config
network.nxos.config.bfd_interfaces:
redirect: cisco.nxos.network.nxos.config.bfd_interfaces
network.nxos.config.bfd_interfaces.bfd_interfaces:
redirect: cisco.nxos.network.nxos.config.bfd_interfaces.bfd_interfaces
network.nxos.config.interfaces:
redirect: cisco.nxos.network.nxos.config.interfaces
network.nxos.config.interfaces.interfaces:
redirect: cisco.nxos.network.nxos.config.interfaces.interfaces
network.nxos.config.l2_interfaces:
redirect: cisco.nxos.network.nxos.config.l2_interfaces
network.nxos.config.l2_interfaces.l2_interfaces:
redirect: cisco.nxos.network.nxos.config.l2_interfaces.l2_interfaces
network.nxos.config.l3_interfaces:
redirect: cisco.nxos.network.nxos.config.l3_interfaces
network.nxos.config.l3_interfaces.l3_interfaces:
redirect: cisco.nxos.network.nxos.config.l3_interfaces.l3_interfaces
network.nxos.config.lacp:
redirect: cisco.nxos.network.nxos.config.lacp
network.nxos.config.lacp.lacp:
redirect: cisco.nxos.network.nxos.config.lacp.lacp
network.nxos.config.lacp_interfaces:
redirect: cisco.nxos.network.nxos.config.lacp_interfaces
network.nxos.config.lacp_interfaces.lacp_interfaces:
redirect: cisco.nxos.network.nxos.config.lacp_interfaces.lacp_interfaces
network.nxos.config.lag_interfaces:
redirect: cisco.nxos.network.nxos.config.lag_interfaces
network.nxos.config.lag_interfaces.lag_interfaces:
redirect: cisco.nxos.network.nxos.config.lag_interfaces.lag_interfaces
network.nxos.config.lldp_global:
redirect: cisco.nxos.network.nxos.config.lldp_global
network.nxos.config.lldp_global.lldp_global:
redirect: cisco.nxos.network.nxos.config.lldp_global.lldp_global
network.nxos.config.telemetry:
redirect: cisco.nxos.network.nxos.config.telemetry
network.nxos.config.telemetry.telemetry:
redirect: cisco.nxos.network.nxos.config.telemetry.telemetry
network.nxos.config.vlans:
redirect: cisco.nxos.network.nxos.config.vlans
network.nxos.config.vlans.vlans:
redirect: cisco.nxos.network.nxos.config.vlans.vlans
network.nxos.facts:
redirect: cisco.nxos.network.nxos.facts
network.nxos.facts.bfd_interfaces:
redirect: cisco.nxos.network.nxos.facts.bfd_interfaces
network.nxos.facts.bfd_interfaces.bfd_interfaces:
redirect: cisco.nxos.network.nxos.facts.bfd_interfaces.bfd_interfaces
network.nxos.facts.facts:
redirect: cisco.nxos.network.nxos.facts.facts
network.nxos.facts.interfaces:
redirect: cisco.nxos.network.nxos.facts.interfaces
network.nxos.facts.interfaces.interfaces:
redirect: cisco.nxos.network.nxos.facts.interfaces.interfaces
network.nxos.facts.l2_interfaces:
redirect: cisco.nxos.network.nxos.facts.l2_interfaces
network.nxos.facts.l2_interfaces.l2_interfaces:
redirect: cisco.nxos.network.nxos.facts.l2_interfaces.l2_interfaces
network.nxos.facts.l3_interfaces:
redirect: cisco.nxos.network.nxos.facts.l3_interfaces
network.nxos.facts.l3_interfaces.l3_interfaces:
redirect: cisco.nxos.network.nxos.facts.l3_interfaces.l3_interfaces
network.nxos.facts.lacp:
redirect: cisco.nxos.network.nxos.facts.lacp
network.nxos.facts.lacp.lacp:
redirect: cisco.nxos.network.nxos.facts.lacp.lacp
network.nxos.facts.lacp_interfaces:
redirect: cisco.nxos.network.nxos.facts.lacp_interfaces
network.nxos.facts.lacp_interfaces.lacp_interfaces:
redirect: cisco.nxos.network.nxos.facts.lacp_interfaces.lacp_interfaces
network.nxos.facts.lag_interfaces:
redirect: cisco.nxos.network.nxos.facts.lag_interfaces
network.nxos.facts.lag_interfaces.lag_interfaces:
redirect: cisco.nxos.network.nxos.facts.lag_interfaces.lag_interfaces
network.nxos.facts.legacy:
redirect: cisco.nxos.network.nxos.facts.legacy
network.nxos.facts.legacy.base:
redirect: cisco.nxos.network.nxos.facts.legacy.base
network.nxos.facts.lldp_global:
redirect: cisco.nxos.network.nxos.facts.lldp_global
network.nxos.facts.lldp_global.lldp_global:
redirect: cisco.nxos.network.nxos.facts.lldp_global.lldp_global
network.nxos.facts.telemetry:
redirect: cisco.nxos.network.nxos.facts.telemetry
network.nxos.facts.telemetry.telemetry:
redirect: cisco.nxos.network.nxos.facts.telemetry.telemetry
network.nxos.facts.vlans:
redirect: cisco.nxos.network.nxos.facts.vlans
network.nxos.facts.vlans.vlans:
redirect: cisco.nxos.network.nxos.facts.vlans.vlans
network.nxos.nxos:
redirect: cisco.nxos.network.nxos.nxos
network.nxos.utils:
redirect: cisco.nxos.network.nxos.utils
network.nxos.utils.telemetry:
redirect: cisco.nxos.network.nxos.utils.telemetry
network.nxos.utils.telemetry.telemetry:
redirect: cisco.nxos.network.nxos.utils.telemetry.telemetry
network.nxos.utils.utils:
redirect: cisco.nxos.network.nxos.utils.utils
network.onyx:
redirect: mellanox.onyx.network.onyx
network.onyx.onyx:
redirect: mellanox.onyx.network.onyx.onyx
network.ordnance:
redirect: community.network.network.ordnance
network.ordnance.ordnance:
redirect: community.network.network.ordnance.ordnance
network.panos:
redirect: community.network.network.panos
network.panos.panos:
redirect: community.network.network.panos.panos
network.restconf:
redirect: ansible.netcommon.network.restconf
network.restconf.restconf:
redirect: ansible.netcommon.network.restconf.restconf
network.routeros:
redirect: community.routeros.routeros
network.routeros.routeros:
redirect: community.routeros.routeros
network.skydive:
redirect: community.skydive.network.skydive
network.skydive.api:
redirect: community.skydive.network.skydive.api
network.slxos:
redirect: community.network.network.slxos
network.slxos.slxos:
redirect: community.network.network.slxos.slxos
network.sros:
redirect: community.network.network.sros
network.sros.sros:
redirect: community.network.network.sros.sros
network.voss:
redirect: community.network.network.voss
network.voss.voss:
redirect: community.network.network.voss.voss
network.vyos:
redirect: vyos.vyos.network.vyos
network.vyos.argspec:
redirect: vyos.vyos.network.vyos.argspec
network.vyos.argspec.facts:
redirect: vyos.vyos.network.vyos.argspec.facts
network.vyos.argspec.facts.facts:
redirect: vyos.vyos.network.vyos.argspec.facts.facts
network.vyos.argspec.interfaces:
redirect: vyos.vyos.network.vyos.argspec.interfaces
network.vyos.argspec.interfaces.interfaces:
redirect: vyos.vyos.network.vyos.argspec.interfaces.interfaces
network.vyos.argspec.l3_interfaces:
redirect: vyos.vyos.network.vyos.argspec.l3_interfaces
network.vyos.argspec.l3_interfaces.l3_interfaces:
redirect: vyos.vyos.network.vyos.argspec.l3_interfaces.l3_interfaces
network.vyos.argspec.lag_interfaces:
redirect: vyos.vyos.network.vyos.argspec.lag_interfaces
network.vyos.argspec.lag_interfaces.lag_interfaces:
redirect: vyos.vyos.network.vyos.argspec.lag_interfaces.lag_interfaces
network.vyos.argspec.lldp_global:
redirect: vyos.vyos.network.vyos.argspec.lldp_global
network.vyos.argspec.lldp_global.lldp_global:
redirect: vyos.vyos.network.vyos.argspec.lldp_global.lldp_global
network.vyos.argspec.lldp_interfaces:
redirect: vyos.vyos.network.vyos.argspec.lldp_interfaces
network.vyos.argspec.lldp_interfaces.lldp_interfaces:
redirect: vyos.vyos.network.vyos.argspec.lldp_interfaces.lldp_interfaces
network.vyos.config:
redirect: vyos.vyos.network.vyos.config
network.vyos.config.interfaces:
redirect: vyos.vyos.network.vyos.config.interfaces
network.vyos.config.interfaces.interfaces:
redirect: vyos.vyos.network.vyos.config.interfaces.interfaces
network.vyos.config.l3_interfaces:
redirect: vyos.vyos.network.vyos.config.l3_interfaces
network.vyos.config.l3_interfaces.l3_interfaces:
redirect: vyos.vyos.network.vyos.config.l3_interfaces.l3_interfaces
network.vyos.config.lag_interfaces:
redirect: vyos.vyos.network.vyos.config.lag_interfaces
network.vyos.config.lag_interfaces.lag_interfaces:
redirect: vyos.vyos.network.vyos.config.lag_interfaces.lag_interfaces
network.vyos.config.lldp_global:
redirect: vyos.vyos.network.vyos.config.lldp_global
network.vyos.config.lldp_global.lldp_global:
redirect: vyos.vyos.network.vyos.config.lldp_global.lldp_global
network.vyos.config.lldp_interfaces:
redirect: vyos.vyos.network.vyos.config.lldp_interfaces
network.vyos.config.lldp_interfaces.lldp_interfaces:
redirect: vyos.vyos.network.vyos.config.lldp_interfaces.lldp_interfaces
network.vyos.facts:
redirect: vyos.vyos.network.vyos.facts
network.vyos.facts.facts:
redirect: vyos.vyos.network.vyos.facts.facts
network.vyos.facts.interfaces:
redirect: vyos.vyos.network.vyos.facts.interfaces
network.vyos.facts.interfaces.interfaces:
redirect: vyos.vyos.network.vyos.facts.interfaces.interfaces
network.vyos.facts.l3_interfaces:
redirect: vyos.vyos.network.vyos.facts.l3_interfaces
network.vyos.facts.l3_interfaces.l3_interfaces:
redirect: vyos.vyos.network.vyos.facts.l3_interfaces.l3_interfaces
network.vyos.facts.lag_interfaces:
redirect: vyos.vyos.network.vyos.facts.lag_interfaces
network.vyos.facts.lag_interfaces.lag_interfaces:
redirect: vyos.vyos.network.vyos.facts.lag_interfaces.lag_interfaces
network.vyos.facts.legacy:
redirect: vyos.vyos.network.vyos.facts.legacy
network.vyos.facts.legacy.base:
redirect: vyos.vyos.network.vyos.facts.legacy.base
network.vyos.facts.lldp_global:
redirect: vyos.vyos.network.vyos.facts.lldp_global
network.vyos.facts.lldp_global.lldp_global:
redirect: vyos.vyos.network.vyos.facts.lldp_global.lldp_global
network.vyos.facts.lldp_interfaces:
redirect: vyos.vyos.network.vyos.facts.lldp_interfaces
network.vyos.facts.lldp_interfaces.lldp_interfaces:
redirect: vyos.vyos.network.vyos.facts.lldp_interfaces.lldp_interfaces
network.vyos.utils:
redirect: vyos.vyos.network.vyos.utils
network.vyos.utils.utils:
redirect: vyos.vyos.network.vyos.utils.utils
network.vyos.vyos:
redirect: vyos.vyos.network.vyos.vyos
oneandone:
redirect: community.general.oneandone
oneview:
redirect: community.general.oneview
online:
redirect: community.general.online
opennebula:
redirect: community.general.opennebula
openstack:
redirect: openstack.cloud.openstack
oracle:
redirect: community.general.oracle
oracle.oci_utils:
redirect: community.general.oracle.oci_utils
ovirt:
redirect: community.general._ovirt
podman:
redirect: containers.podman.podman
podman.common:
redirect: containers.podman.podman.common
postgres:
redirect: community.postgresql.postgres
pure:
redirect: community.general.pure
rabbitmq:
redirect: community.rabbitmq.rabbitmq
rax:
redirect: community.general.rax
redfish_utils:
redirect: community.general.redfish_utils
redhat:
redirect: community.general.redhat
remote_management.dellemc:
redirect: dellemc.openmanage
remote_management.dellemc.dellemc_idrac:
redirect: dellemc.openmanage.dellemc_idrac
remote_management.dellemc.ome:
redirect: dellemc.openmanage.ome
remote_management.intersight:
redirect: cisco.intersight.intersight
remote_management.lxca:
redirect: community.general.remote_management.lxca
remote_management.lxca.common:
redirect: community.general.remote_management.lxca.common
remote_management.ucs:
redirect: cisco.ucs.ucs
scaleway:
redirect: community.general.scaleway
service_now:
redirect: servicenow.servicenow.service_now
source_control:
redirect: community.general.source_control
source_control.bitbucket:
redirect: community.general.source_control.bitbucket
storage:
redirect: community.general.storage
storage.emc:
redirect: community.general.storage.emc
storage.emc.emc_vnx:
redirect: community.general.storage.emc.emc_vnx
storage.hpe3par:
redirect: community.general.storage.hpe3par
storage.hpe3par.hpe3par:
redirect: community.general.storage.hpe3par.hpe3par
univention_umc:
redirect: community.general.univention_umc
utm_utils:
redirect: community.general.utm_utils
vca:
redirect: community.vmware.vca
vexata:
redirect: community.general.vexata
vmware:
redirect: community.vmware.vmware
vmware_rest_client:
redirect: community.vmware.vmware_rest_client
vmware_spbm:
redirect: community.vmware.vmware_spbm
vultr:
redirect: ngine_io.vultr.vultr
xenserver:
redirect: community.general.xenserver
# end module_utils
cliconf:
frr:
redirect: frr.frr.frr
aireos:
redirect: community.network.aireos
apconos:
redirect: community.network.apconos
aruba:
redirect: community.network.aruba
ce:
redirect: community.network.ce
cnos:
redirect: community.network.cnos
edgeos:
redirect: community.network.edgeos
edgeswitch:
redirect: community.network.edgeswitch
enos:
redirect: community.network.enos
eric_eccli:
redirect: community.network.eric_eccli
exos:
redirect: community.network.exos
icx:
redirect: community.network.icx
ironware:
redirect: community.network.ironware
netvisor:
redirect: community.network.netvisor
nos:
redirect: community.network.nos
onyx:
redirect: mellanox.onyx.onyx
routeros:
redirect: community.routeros.routeros
slxos:
redirect: community.network.slxos
voss:
redirect: community.network.voss
eos:
redirect: arista.eos.eos
asa:
redirect: cisco.asa.asa
ios:
redirect: cisco.ios.ios
iosxr:
redirect: cisco.iosxr.iosxr
nxos:
redirect: cisco.nxos.nxos
junos:
redirect: junipernetworks.junos.junos
dellos10:
redirect: dellemc.os10.os10
dellos9:
redirect: dellemc.os9.os9
dellos6:
redirect: dellemc.os6.os6
vyos:
redirect: vyos.vyos.vyos
terminal:
frr:
redirect: frr.frr.frr
aireos:
redirect: community.network.aireos
apconos:
redirect: community.network.apconos
aruba:
redirect: community.network.aruba
ce:
redirect: community.network.ce
cnos:
redirect: community.network.cnos
edgeos:
redirect: community.network.edgeos
edgeswitch:
redirect: community.network.edgeswitch
enos:
redirect: community.network.enos
eric_eccli:
redirect: community.network.eric_eccli
exos:
redirect: community.network.exos
icx:
redirect: community.network.icx
ironware:
redirect: community.network.ironware
netvisor:
redirect: community.network.netvisor
nos:
redirect: community.network.nos
onyx:
redirect: mellanox.onyx.onyx
routeros:
redirect: community.routeros.routeros
slxos:
redirect: community.network.slxos
sros:
redirect: community.network.sros
voss:
redirect: community.network.voss
eos:
redirect: arista.eos.eos
asa:
redirect: cisco.asa.asa
ios:
redirect: cisco.ios.ios
iosxr:
redirect: cisco.iosxr.iosxr
nxos:
redirect: cisco.nxos.nxos
bigip:
redirect: f5networks.f5_modules.bigip
junos:
redirect: junipernetworks.junos.junos
dellos10:
redirect: dellemc.os10.os10
dellos9:
redirect: dellemc.os9.os9
dellos6:
redirect: dellemc.os6.os6
vyos:
redirect: vyos.vyos.vyos
action:
# test entry, overloaded with module of same name to use a different base action (ie not "normal.py")
uses_redirected_action:
redirect: testns.testcoll.subclassed_norm
aireos:
redirect: community.network.aireos
aruba:
redirect: community.network.aruba
ce:
redirect: community.network.ce
ce_template:
redirect: community.network.ce_template
cnos:
redirect: community.network.cnos
edgeos_config:
redirect: community.network.edgeos_config
enos:
redirect: community.network.enos
exos:
redirect: community.network.exos
ironware:
redirect: community.network.ironware
nos_config:
redirect: community.network.nos_config
onyx_config:
redirect: mellanox.onyx.onyx_config
slxos:
redirect: community.network.slxos
sros:
redirect: community.network.sros
voss:
redirect: community.network.voss
aws_s3:
redirect: amazon.aws.aws_s3
cli_command:
redirect: ansible.netcommon.cli_command
cli_config:
redirect: ansible.netcommon.cli_config
net_base:
redirect: ansible.netcommon.net_base
net_user:
redirect: ansible.netcommon.net_user
net_vlan:
redirect: ansible.netcommon.net_vlan
net_static_route:
redirect: ansible.netcommon.net_static_route
net_lldp:
redirect: ansible.netcommon.net_lldp
net_vrf:
redirect: ansible.netcommon.net_vrf
net_ping:
redirect: ansible.netcommon.net_ping
net_l3_interface:
redirect: ansible.netcommon.net_l3_interface
net_l2_interface:
redirect: ansible.netcommon.net_l2_interface
net_interface:
redirect: ansible.netcommon.net_interface
net_system:
redirect: ansible.netcommon.net_system
net_lldp_interface:
redirect: ansible.netcommon.net_lldp_interface
net_put:
redirect: ansible.netcommon.net_put
net_get:
redirect: ansible.netcommon.net_get
net_logging:
redirect: ansible.netcommon.net_logging
net_banner:
redirect: ansible.netcommon.net_banner
net_linkagg:
redirect: ansible.netcommon.net_linkagg
netconf:
redirect: ansible.netcommon.netconf
network:
redirect: ansible.netcommon.network
telnet:
redirect: ansible.netcommon.telnet
patch:
redirect: ansible.posix.patch
synchronize:
redirect: ansible.posix.synchronize
win_copy:
redirect: ansible.windows.win_copy
win_reboot:
redirect: ansible.windows.win_reboot
win_template:
redirect: ansible.windows.win_template
win_updates:
redirect: ansible.windows.win_updates
fortios_config:
redirect: fortinet.fortios.fortios_config
eos:
redirect: arista.eos.eos
asa:
redirect: cisco.asa.asa
ios:
redirect: cisco.ios.ios
iosxr:
redirect: cisco.iosxr.iosxr
nxos:
redirect: cisco.nxos.nxos
nxos_file_copy:
redirect: cisco.nxos.nxos_file_copy
bigip:
redirect: f5networks.f5_modules.bigip
bigiq:
redirect: f5networks.f5_modules.bigiq
junos:
redirect: junipernetworks.junos.junos
dellos10:
redirect: dellemc.os10.os10
dellos9:
redirect: dellemc.os9.os9
dellos6:
redirect: dellemc.os6.os6
vyos:
redirect: vyos.vyos.vyos
include:
tombstone:
removal_date: "2023-05-16"
warning_text: Use include_tasks or import_tasks instead.
yum:
redirect: ansible.builtin.dnf
become:
doas:
redirect: community.general.doas
dzdo:
redirect: community.general.dzdo
ksu:
redirect: community.general.ksu
machinectl:
redirect: community.general.machinectl
pbrun:
redirect: community.general.pbrun
pfexec:
redirect: community.general.pfexec
pmrun:
redirect: community.general.pmrun
sesu:
redirect: community.general.sesu
enable:
redirect: ansible.netcommon.enable
cache:
memcached:
redirect: community.general.memcached
pickle:
redirect: community.general.pickle
redis:
redirect: community.general.redis
yaml:
redirect: community.general.yaml
mongodb:
redirect: community.mongodb.mongodb
callback:
actionable:
redirect: community.general.actionable
cgroup_memory_recap:
redirect: community.general.cgroup_memory_recap
context_demo:
redirect: community.general.context_demo
counter_enabled:
redirect: community.general.counter_enabled
dense:
redirect: community.general.dense
full_skip:
redirect: community.general.full_skip
hipchat:
redirect: community.general.hipchat
jabber:
redirect: community.general.jabber
log_plays:
redirect: community.general.log_plays
logdna:
redirect: community.general.logdna
logentries:
redirect: community.general.logentries
logstash:
redirect: community.general.logstash
mail:
redirect: community.general.mail
nrdp:
redirect: community.general.nrdp
'null':
redirect: community.general.null
osx_say:
redirect: community.general.osx_say
say:
redirect: community.general.say
selective:
redirect: community.general.selective
slack:
redirect: community.general.slack
splunk:
redirect: community.general.splunk
stderr:
redirect: community.general.stderr
sumologic:
redirect: community.general.sumologic
syslog_json:
redirect: community.general.syslog_json
unixy:
redirect: community.general.unixy
yaml:
redirect: community.general.yaml
grafana_annotations:
redirect: community.grafana.grafana_annotations
aws_resource_actions:
redirect: amazon.aws.aws_resource_actions
cgroup_perf_recap:
redirect: ansible.posix.cgroup_perf_recap
debug:
redirect: ansible.posix.debug
json:
redirect: ansible.posix.json
profile_roles:
redirect: ansible.posix.profile_roles
profile_tasks:
redirect: ansible.posix.profile_tasks
skippy:
redirect: ansible.posix.skippy
timer:
redirect: ansible.posix.timer
foreman:
redirect: theforeman.foreman.foreman
# 'collections' integration test entries, do not remove
formerly_core_callback:
redirect: testns.testcoll.usercallback
formerly_core_removed_callback:
redirect: testns.testcoll.removedcallback
formerly_core_missing_callback:
redirect: bogusns.boguscoll.boguscallback
doc_fragments:
a10:
redirect: community.network.a10
aireos:
redirect: community.network.aireos
alicloud:
redirect: community.general.alicloud
aruba:
redirect: community.network.aruba
auth_basic:
redirect: community.general.auth_basic
avi:
redirect: community.network.avi
ce:
redirect: community.network.ce
cloudscale:
redirect: cloudscale_ch.cloud.api_parameters
cloudstack:
redirect: ngine_io.cloudstack.cloudstack
cnos:
redirect: community.network.cnos
digital_ocean:
redirect: community.digitalocean.digital_ocean
dimensiondata:
redirect: community.general.dimensiondata
dimensiondata_wait:
redirect: community.general.dimensiondata_wait
docker:
redirect: community.docker.docker
emc:
redirect: community.general.emc
enos:
redirect: community.network.enos
exoscale:
redirect: ngine_io.exoscale.exoscale
gcp:
redirect: google.cloud.gcp
hetzner:
redirect: community.hrobot.robot
hpe3par:
redirect: community.general.hpe3par
hwc:
redirect: community.general.hwc
ibm_storage:
redirect: community.general.ibm_storage
infinibox:
redirect: infinidat.infinibox.infinibox
influxdb:
redirect: community.general.influxdb
ingate:
redirect: community.network.ingate
ipa:
redirect: community.general.ipa
ironware:
redirect: community.network.ironware
keycloak:
redirect: community.general.keycloak
kubevirt_common_options:
redirect: community.kubevirt.kubevirt_common_options
kubevirt_vm_options:
redirect: community.kubevirt.kubevirt_vm_options
ldap:
redirect: community.general.ldap
lxca_common:
redirect: community.general.lxca_common
manageiq:
redirect: community.general.manageiq
mysql:
redirect: community.mysql.mysql
netscaler:
redirect: community.network.netscaler
nios:
redirect: community.general.nios
nso:
redirect: cisco.nso.nso
oneview:
redirect: community.general.oneview
online:
redirect: community.general.online
onyx:
redirect: mellanox.onyx.onyx
opennebula:
redirect: community.general.opennebula
openswitch:
redirect: community.general.openswitch
oracle:
redirect: community.general.oracle
oracle_creatable_resource:
redirect: community.general.oracle_creatable_resource
oracle_display_name_option:
redirect: community.general.oracle_display_name_option
oracle_name_option:
redirect: community.general.oracle_name_option
oracle_tags:
redirect: community.general.oracle_tags
oracle_wait_options:
redirect: community.general.oracle_wait_options
ovirt_facts:
redirect: community.general.ovirt_facts
panos:
redirect: community.network.panos
postgres:
redirect: community.postgresql.postgres
proxysql:
redirect: community.proxysql.proxysql
purestorage:
redirect: community.general.purestorage
rabbitmq:
redirect: community.rabbitmq.rabbitmq
rackspace:
redirect: community.general.rackspace
scaleway:
redirect: community.general.scaleway
sros:
redirect: community.network.sros
utm:
redirect: community.general.utm
vexata:
redirect: community.general.vexata
vultr:
redirect: ngine_io.vultr.vultr
xenserver:
redirect: community.general.xenserver
zabbix:
redirect: community.zabbix.zabbix
k8s_auth_options:
redirect: kubernetes.core.k8s_auth_options
k8s_name_options:
redirect: kubernetes.core.k8s_name_options
k8s_resource_options:
redirect: kubernetes.core.k8s_resource_options
k8s_scale_options:
redirect: kubernetes.core.k8s_scale_options
k8s_state_options:
redirect: kubernetes.core.k8s_state_options
acme:
redirect: community.crypto.acme
ecs_credential:
redirect: community.crypto.ecs_credential
VmwareRestModule:
redirect: vmware.vmware_rest.VmwareRestModule
VmwareRestModule_filters:
redirect: vmware.vmware_rest.VmwareRestModule_filters
VmwareRestModule_full:
redirect: vmware.vmware_rest.VmwareRestModule_full
VmwareRestModule_state:
redirect: vmware.vmware_rest.VmwareRestModule_state
vca:
redirect: community.vmware.vca
vmware:
redirect: community.vmware.vmware
vmware_rest_client:
redirect: community.vmware.vmware_rest_client
service_now:
redirect: servicenow.servicenow.service_now
aws:
redirect: amazon.aws.aws
aws_credentials:
redirect: amazon.aws.aws_credentials
aws_region:
redirect: amazon.aws.aws_region
ec2:
redirect: amazon.aws.ec2
netconf:
redirect: ansible.netcommon.netconf
network_agnostic:
redirect: ansible.netcommon.network_agnostic
fortios:
redirect: fortinet.fortios.fortios
netapp:
redirect: netapp.ontap.netapp
checkpoint_commands:
redirect: check_point.mgmt.checkpoint_commands
checkpoint_facts:
redirect: check_point.mgmt.checkpoint_facts
checkpoint_objects:
redirect: check_point.mgmt.checkpoint_objects
eos:
redirect: arista.eos.eos
aci:
redirect: cisco.aci.aci
asa:
redirect: cisco.asa.asa
intersight:
redirect: cisco.intersight.intersight
ios:
redirect: cisco.ios.ios
iosxr:
redirect: cisco.iosxr.iosxr
meraki:
redirect: cisco.meraki.meraki
mso:
redirect: cisco.mso.modules
nxos:
redirect: cisco.nxos.nxos
ucs:
redirect: cisco.ucs.ucs
f5:
redirect: f5networks.f5_modules.f5
openstack:
redirect: openstack.cloud.openstack
junos:
redirect: junipernetworks.junos.junos
tower:
redirect: awx.awx.auth
ovirt:
redirect: ovirt.ovirt.ovirt
ovirt_info:
redirect: ovirt.ovirt.ovirt_info
dellos10:
redirect: dellemc.os10.os10
dellos9:
redirect: dellemc.os9.os9
dellos6:
redirect: dellemc.os6.os6
hcloud:
redirect: hetzner.hcloud.hcloud
skydive:
redirect: community.skydive.skydive
azure:
redirect: azure.azcollection.azure
azure_tags:
redirect: azure.azcollection.azure_tags
vyos:
redirect: vyos.vyos.vyos
filter:
# test entries
formerly_core_filter:
redirect: ansible.builtin.bool
formerly_core_masked_filter:
redirect: ansible.builtin.bool
gcp_kms_encrypt:
redirect: google.cloud.gcp_kms_encrypt
gcp_kms_decrypt:
redirect: google.cloud.gcp_kms_decrypt
json_query:
redirect: community.general.json_query
random_mac:
redirect: community.general.random_mac
k8s_config_resource_name:
redirect: kubernetes.core.k8s_config_resource_name
cidr_merge:
redirect: ansible.netcommon.cidr_merge
ipaddr:
redirect: ansible.netcommon.ipaddr
ipmath:
redirect: ansible.netcommon.ipmath
ipwrap:
redirect: ansible.netcommon.ipwrap
ip4_hex:
redirect: ansible.netcommon.ip4_hex
ipv4:
redirect: ansible.netcommon.ipv4
ipv6:
redirect: ansible.netcommon.ipv6
ipsubnet:
redirect: ansible.netcommon.ipsubnet
next_nth_usable:
redirect: ansible.netcommon.next_nth_usable
network_in_network:
redirect: ansible.netcommon.network_in_network
network_in_usable:
redirect: ansible.netcommon.network_in_usable
reduce_on_network:
redirect: ansible.netcommon.reduce_on_network
nthhost:
redirect: ansible.netcommon.nthhost
previous_nth_usable:
redirect: ansible.netcommon.previous_nth_usable
slaac:
redirect: ansible.netcommon.slaac
hwaddr:
redirect: ansible.netcommon.hwaddr
parse_cli:
redirect: ansible.netcommon.parse_cli
parse_cli_textfsm:
redirect: ansible.netcommon.parse_cli_textfsm
parse_xml:
redirect: ansible.netcommon.parse_xml
type5_pw:
redirect: ansible.netcommon.type5_pw
hash_salt:
redirect: ansible.netcommon.hash_salt
comp_type5:
redirect: ansible.netcommon.comp_type5
vlan_parser:
redirect: ansible.netcommon.vlan_parser
httpapi:
exos:
redirect: community.network.exos
fortianalyzer:
redirect: community.fortios.fortianalyzer
fortimanager:
redirect: fortinet.fortimanager.fortimanager
ftd:
redirect: community.network.ftd
vmware:
redirect: community.vmware.vmware
restconf:
redirect: ansible.netcommon.restconf
fortios:
redirect: fortinet.fortios.fortios
checkpoint:
redirect: check_point.mgmt.checkpoint
eos:
redirect: arista.eos.eos
nxos:
redirect: cisco.nxos.nxos
splunk:
redirect: splunk.es.splunk
qradar:
redirect: ibm.qradar.qradar
inventory:
# test entry
formerly_core_inventory:
redirect: testns.content_adj.statichost
cloudscale:
redirect: cloudscale_ch.cloud.inventory
docker_machine:
redirect: community.docker.docker_machine
docker_swarm:
redirect: community.docker.docker_swarm
gitlab_runners:
redirect: community.general.gitlab_runners
kubevirt:
redirect: community.kubevirt.kubevirt
linode:
redirect: community.general.linode
nmap:
redirect: community.general.nmap
online:
redirect: community.general.online
scaleway:
redirect: community.general.scaleway
virtualbox:
redirect: community.general.virtualbox
vultr:
redirect: ngine_io.vultr.vultr
k8s:
redirect: kubernetes.core.k8s
openshift:
redirect: kubernetes.core.openshift
vmware_vm_inventory:
redirect: community.vmware.vmware_vm_inventory
aws_ec2:
redirect: amazon.aws.aws_ec2
aws_rds:
redirect: amazon.aws.aws_rds
foreman:
redirect: theforeman.foreman.foreman
netbox:
redirect: netbox.netbox.nb_inventory
openstack:
redirect: openstack.cloud.openstack
tower:
redirect: awx.awx.tower
hcloud:
redirect: hetzner.hcloud.hcloud
gcp_compute:
redirect: google.cloud.gcp_compute
azure_rm:
redirect: azure.azcollection.azure_rm
lookup:
# test entry
formerly_core_lookup:
redirect: testns.testcoll.mylookup
avi:
redirect: community.network.avi
cartesian:
redirect: community.general.cartesian
chef_databag:
redirect: community.general.chef_databag
conjur_variable:
redirect: cyberark.conjur.conjur_variable
consul_kv:
redirect: community.general.consul_kv
credstash:
redirect: community.general.credstash
cyberarkpassword:
redirect: community.general.cyberarkpassword
dig:
redirect: community.general.dig
dnstxt:
redirect: community.general.dnstxt
etcd:
redirect: community.general.etcd
filetree:
redirect: community.general.filetree
flattened:
redirect: community.general.flattened
gcp_storage_file:
redirect: community.google.gcp_storage_file
hashi_vault:
redirect: community.hashi_vault.hashi_vault
hiera:
redirect: community.general.hiera
keyring:
redirect: community.general.keyring
lastpass:
redirect: community.general.lastpass
lmdb_kv:
redirect: community.general.lmdb_kv
manifold:
redirect: community.general.manifold
nios:
redirect: community.general.nios
nios_next_ip:
redirect: community.general.nios_next_ip
nios_next_network:
redirect: community.general.nios_next_network
onepassword:
redirect: community.general.onepassword
onepassword_raw:
redirect: community.general.onepassword_raw
passwordstore:
redirect: community.general.passwordstore
rabbitmq:
redirect: community.rabbitmq.rabbitmq
redis:
redirect: community.general.redis
shelvefile:
redirect: community.general.shelvefile
grafana_dashboard:
redirect: community.grafana.grafana_dashboard
openshift:
redirect: kubernetes.core.openshift
k8s:
redirect: kubernetes.core.k8s
mongodb:
redirect: community.mongodb.mongodb
laps_password:
redirect: community.windows.laps_password
aws_account_attribute:
redirect: amazon.aws.aws_account_attribute
aws_secret:
redirect: amazon.aws.aws_secret
aws_service_ip_ranges:
redirect: amazon.aws.aws_service_ip_ranges
aws_ssm:
redirect: amazon.aws.aws_ssm
skydive:
redirect: community.skydive.skydive
cpm_metering:
redirect: wti.remote.cpm_metering
cpm_status:
redirect: wti.remote.cpm_status
netconf:
ce:
redirect: community.network.ce
sros:
redirect: community.network.sros
default:
redirect: ansible.netcommon.default
iosxr:
redirect: cisco.iosxr.iosxr
junos:
redirect: junipernetworks.junos.junos
shell:
# test entry
formerly_core_powershell:
redirect: ansible.builtin.powershell
csh:
redirect: ansible.posix.csh
fish:
redirect: ansible.posix.fish
test:
# test entries
formerly_core_test:
redirect: ansible.builtin.search
formerly_core_masked_test:
redirect: ansible.builtin.search
import_redirection:
# test entry
ansible.module_utils.formerly_core:
redirect: ansible_collections.testns.testcoll.plugins.module_utils.base
ansible.module_utils.known_hosts:
redirect: ansible_collections.community.general.plugins.module_utils.known_hosts
# ansible.builtin synthetic collection redirection hackery
ansible_collections.ansible.builtin.plugins.modules:
redirect: ansible.modules
ansible_collections.ansible.builtin.plugins.module_utils:
redirect: ansible.module_utils
ansible_collections.ansible.builtin.plugins:
redirect: ansible.plugins
action_groups:
testgroup:
# The list items under a group should always be action/module name strings except
# for a special 'metadata' dictionary.
# The only valid key currently for the metadata dictionary is 'extend_group', which is a
# list of other groups, the actions of which will be included in this group.
# (Note: it's still possible to also have a module/action named 'metadata' in the list)
- metadata:
extend_group:
- testns.testcoll.testgroup
- testns.testcoll.anothergroup
- testns.boguscoll.testgroup
- ping
- legacy_ping # Includes ansible.builtin.legacy_ping, not ansible.legacy.legacy_ping
- formerly_core_ping
testlegacy:
- ansible.legacy.legacy_ping
aws:
- metadata:
extend_group:
- amazon.aws.aws
- community.aws.aws
acme:
- metadata:
extend_group:
- community.crypto.acme
azure:
- metadata:
extend_group:
- azure.azcollection.azure
cpm:
- metadata:
extend_group:
- wti.remote.cpm
docker:
- metadata:
extend_group:
- community.general.docker
- community.docker.docker
gcp:
- metadata:
extend_group:
- google.cloud.gcp
k8s:
- metadata:
extend_group:
- community.kubernetes.k8s
- community.general.k8s
- community.kubevirt.k8s
- community.okd.k8s
- kubernetes.core.k8s
os:
- metadata:
extend_group:
- openstack.cloud.os
ovirt:
- metadata:
extend_group:
- ovirt.ovirt.ovirt
- community.general.ovirt
vmware:
- metadata:
extend_group:
- community.vmware.vmware
ansible_core-2.19.0b4/lib/ansible/config/base.yml 0000644 0000000 0000000 00000255142 15010426755 020317 0 ustar 00root root # Copyright (c) 2017 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
---
_ANSIBLE_CONNECTION_PATH:
env:
- name: _ANSIBLE_CONNECTION_PATH
name: Overrides the location of the Ansible persistent connection helper script.
description:
- For internal use only.
type: path
version_added: "2.18"
_CALLBACK_DISPATCH_ERROR_BEHAVIOR:
name: Callback dispatch error behavior
default: warning
description:
- Action to take when a callback dispatch results in an error.
type: choices
choices: &basic_error
error: issue a 'fatal' error and stop the play
warning: issue a warning but continue
ignore: just continue silently
env: [ { name: _ANSIBLE_CALLBACK_DISPATCH_ERROR_BEHAVIOR } ]
version_added: '2.19'
ALLOW_BROKEN_CONDITIONALS:
# This config option will be deprecated once it no longer has any effect (2.23).
name: Allow broken conditionals
default: false
description:
- When enabled, this option allows conditionals with non-boolean results to be used.
- A deprecation warning will be emitted in these cases.
- By default, non-boolean conditionals result in an error.
- Such results often indicate unintentional use of templates where they are not supported, resulting in a conditional that is always true.
- When this option is enabled, conditional expressions which are a literal ``None`` or empty string will evaluate as true for backwards compatibility.
env: [{name: ANSIBLE_ALLOW_BROKEN_CONDITIONALS}]
ini:
- {key: allow_broken_conditionals, section: defaults}
type: boolean
version_added: "2.19"
ALLOW_EMBEDDED_TEMPLATES:
name: Allow embedded templates
default: true
description:
- When enabled, this option allows embedded templates to be used for specific backward compatibility scenarios.
- A deprecation warning will be emitted in these cases.
- First, conditionals (for example, ``failed_when``, ``until``, ``assert.that``) fully enclosed in template delimiters.
- "Second, string constants in conditionals (for example, ``when: some_var == '{{ some_other_var }}'``)."
- Finally, positional arguments to lookups (for example, ``lookup('pipe', 'echo {{ some_var }}')``).
- This feature is deprecated, since embedded templates are unnecessary in these cases.
- When disabled, use of embedded templates will result in an error.
- A future release will disable this feature by default.
env: [{name: ANSIBLE_ALLOW_EMBEDDED_TEMPLATES}]
ini:
- {key: allow_embedded_templates, section: defaults}
type: boolean
version_added: "2.19"
ANSIBLE_HOME:
name: The Ansible home path
description:
- The default root path for Ansible config files on the controller.
default: ~/.ansible
env:
- name: ANSIBLE_HOME
ini:
- key: home
section: defaults
type: path
version_added: '2.14'
ANSIBLE_CONNECTION_PATH:
name: Path of ansible-connection script
default: null
description:
- Specify where to look for the ansible-connection script. This location will be checked before searching $PATH.
- If null, ansible will start with the same directory as the ansible script.
type: path
env: [{name: ANSIBLE_CONNECTION_PATH}]
ini:
- {key: ansible_connection_path, section: persistent_connection}
yaml: {key: persistent_connection.ansible_connection_path}
version_added: "2.8"
deprecated:
why: This setting has no effect.
version: "2.22"
ANSIBLE_COW_SELECTION:
name: Cowsay filter selection
default: default
description: This allows you to choose a specific cowsay stencil for the banners or use 'random' to cycle through them.
env: [{name: ANSIBLE_COW_SELECTION}]
ini:
- {key: cow_selection, section: defaults}
ANSIBLE_COW_ACCEPTLIST:
name: Cowsay filter acceptance list
default: ['bud-frogs', 'bunny', 'cheese', 'daemon', 'default', 'dragon', 'elephant-in-snake', 'elephant', 'eyes', 'hellokitty', 'kitty', 'luke-koala', 'meow', 'milk', 'moofasa', 'moose', 'ren', 'sheep', 'small', 'stegosaurus', 'stimpy', 'supermilker', 'three-eyes', 'turkey', 'turtle', 'tux', 'udder', 'vader-koala', 'vader', 'www']
description: Accept a list of cowsay templates that are 'safe' to use, set to an empty list if you want to enable all installed templates.
env:
- name: ANSIBLE_COW_ACCEPTLIST
version_added: '2.11'
ini:
- key: cowsay_enabled_stencils
section: defaults
version_added: '2.11'
type: list
ANSIBLE_FORCE_COLOR:
name: Force color output
default: False
description: This option forces color mode even when running without a TTY or the "nocolor" setting is True.
env: [{name: ANSIBLE_FORCE_COLOR}]
ini:
- {key: force_color, section: defaults}
type: boolean
yaml: {key: display.force_color}
ANSIBLE_NOCOLOR:
name: Suppress color output
default: False
description: This setting allows suppressing colorizing output, which is used to give a better indication of failure and status information.
env:
- name: ANSIBLE_NOCOLOR
# this is generic convention for CLI programs
- name: NO_COLOR
version_added: '2.11'
ini:
- {key: nocolor, section: defaults}
type: boolean
yaml: {key: display.nocolor}
ANSIBLE_NOCOWS:
name: Suppress cowsay output
default: False
description: If you have cowsay installed but want to avoid the 'cows' (why????), use this.
env: [{name: ANSIBLE_NOCOWS}]
ini:
- {key: nocows, section: defaults}
type: boolean
yaml: {key: display.i_am_no_fun}
ANSIBLE_COW_PATH:
name: Set path to cowsay command
default: null
description: Specify a custom cowsay path or swap in your cowsay implementation of choice.
env: [{name: ANSIBLE_COW_PATH}]
ini:
- {key: cowpath, section: defaults}
type: string
yaml: {key: display.cowpath}
ANSIBLE_PIPELINING:
name: Connection pipelining
default: False
description:
- This is a global option, each connection plugin can override either by having more specific options or not supporting pipelining at all.
- Pipelining, if supported by the connection plugin, reduces the number of network operations required to execute a module on the remote server,
by executing many Ansible modules without actual file transfer.
- It 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."
- This setting will be disabled if ``ANSIBLE_KEEP_REMOTE_FILES`` is enabled.
env:
- name: ANSIBLE_PIPELINING
ini:
- section: defaults
key: pipelining
- section: connection
key: pipelining
type: boolean
ANY_ERRORS_FATAL:
name: Make Task failures fatal
default: False
description: Sets the default value for the any_errors_fatal keyword, if True, Task failures will be considered fatal errors.
env:
- name: ANSIBLE_ANY_ERRORS_FATAL
ini:
- section: defaults
key: any_errors_fatal
type: boolean
yaml: {key: errors.any_task_errors_fatal}
version_added: "2.4"
BECOME_ALLOW_SAME_USER:
name: Allow becoming the same user
default: False
description:
- When ``False``(default), Ansible will skip using become if the remote user is the same as the become user, as this is normally a redundant operation.
In other words root sudo to root.
- If ``True``, this forces Ansible to use the become plugin anyways as there are cases in which this is needed.
env: [{name: ANSIBLE_BECOME_ALLOW_SAME_USER}]
ini:
- {key: become_allow_same_user, section: privilege_escalation}
type: boolean
yaml: {key: privilege_escalation.become_allow_same_user}
BECOME_PASSWORD_FILE:
name: Become password file
default: ~
description:
- 'The password file to use for the become plugin. ``--become-password-file``.'
- If executable, it will be run and the resulting stdout will be used as the password.
env: [{name: ANSIBLE_BECOME_PASSWORD_FILE}]
ini:
- {key: become_password_file, section: defaults}
type: path
version_added: '2.12'
AGNOSTIC_BECOME_PROMPT:
name: Display an agnostic become prompt
default: True
type: boolean
description: Display an agnostic become prompt instead of displaying a prompt containing the command line supplied become method.
env: [{name: ANSIBLE_AGNOSTIC_BECOME_PROMPT}]
ini:
- {key: agnostic_become_prompt, section: privilege_escalation}
yaml: {key: privilege_escalation.agnostic_become_prompt}
version_added: "2.5"
CACHE_PLUGIN:
name: Persistent Fact Cache plugin
default: memory
description: Chooses which fact cache plugin to use. By default, no cache is used and facts do not persist between runs.
env: [{name: ANSIBLE_CACHE_PLUGIN}]
ini:
- {key: fact_caching, section: defaults}
yaml: {key: facts.cache.plugin}
CACHE_PLUGIN_CONNECTION:
name: Fact Cache Plugin URI
default: ~
description: Defines connection or path information for the fact cache plugin.
env: [{name: ANSIBLE_CACHE_PLUGIN_CONNECTION}]
ini:
- {key: fact_caching_connection, section: defaults}
yaml: {key: facts.cache.uri}
CACHE_PLUGIN_PREFIX:
name: Fact Cache Plugin table prefix
default: ansible_facts
description: Prefix to use for fact cache plugin files/tables.
env: [{name: ANSIBLE_CACHE_PLUGIN_PREFIX}]
ini:
- {key: fact_caching_prefix, section: defaults}
yaml: {key: facts.cache.prefix}
CACHE_PLUGIN_TIMEOUT:
name: Fact Cache Plugin expiration timeout
default: 86400
description: Expiration timeout for the fact cache plugin data.
env: [{name: ANSIBLE_CACHE_PLUGIN_TIMEOUT}]
ini:
- {key: fact_caching_timeout, section: defaults}
type: integer
yaml: {key: facts.cache.timeout}
COLLECTIONS_SCAN_SYS_PATH:
name: Scan PYTHONPATH for installed collections
description: A boolean to enable or disable scanning the sys.path for installed collections.
default: true
type: boolean
env:
- {name: ANSIBLE_COLLECTIONS_SCAN_SYS_PATH}
ini:
- {key: collections_scan_sys_path, section: defaults}
COLLECTIONS_PATHS:
name: An ordered list of root paths for loading installed Ansible collections content.
description: >
Colon-separated paths in which Ansible will search for collections content.
Collections must be in nested *subdirectories*, not directly in these directories.
For example, if ``COLLECTIONS_PATHS`` includes ``'{{ ANSIBLE_HOME ~ "/collections" }}'``,
and you want to add ``my.collection`` to that directory, it must be saved as
``'{{ ANSIBLE_HOME} ~ "/collections/ansible_collections/my/collection" }}'``.
default: '{{ ANSIBLE_HOME ~ "/collections:/usr/share/ansible/collections" }}'
type: pathspec
env:
- name: ANSIBLE_COLLECTIONS_PATH
version_added: '2.10'
ini:
- key: collections_path
section: defaults
version_added: '2.10'
COLLECTIONS_ON_ANSIBLE_VERSION_MISMATCH:
name: Defines behavior when loading a collection that does not support the current Ansible version
description:
- When a collection is loaded that does not support the running Ansible version (with the collection metadata key `requires_ansible`).
env: [{name: ANSIBLE_COLLECTIONS_ON_ANSIBLE_VERSION_MISMATCH}]
ini: [{key: collections_on_ansible_version_mismatch, section: defaults}]
choices: *basic_error
default: warning
COLOR_CHANGED:
name: Color for 'changed' task status
default: yellow
description: Defines the color to use on 'Changed' task status.
env: [{name: ANSIBLE_COLOR_CHANGED}]
ini:
- {key: changed, section: colors}
COLOR_CONSOLE_PROMPT:
name: "Color for ansible-console's prompt task status"
default: white
description: Defines the default color to use for ansible-console.
env: [{name: ANSIBLE_COLOR_CONSOLE_PROMPT}]
ini:
- {key: console_prompt, section: colors}
version_added: "2.7"
COLOR_DEBUG:
name: Color for debug statements
default: dark gray
description: Defines the color to use when emitting debug messages.
env: [{name: ANSIBLE_COLOR_DEBUG}]
ini:
- {key: debug, section: colors}
COLOR_DEPRECATE:
name: Color for deprecation messages
default: purple
description: Defines the color to use when emitting deprecation messages.
env: [{name: ANSIBLE_COLOR_DEPRECATE}]
ini:
- {key: deprecate, section: colors}
COLOR_DIFF_ADD:
name: Color for diff added display
default: green
description: Defines the color to use when showing added lines in diffs.
env: [{name: ANSIBLE_COLOR_DIFF_ADD}]
ini:
- {key: diff_add, section: colors}
yaml: {key: display.colors.diff.add}
COLOR_DIFF_LINES:
name: Color for diff lines display
default: cyan
description: Defines the color to use when showing diffs.
env: [{name: ANSIBLE_COLOR_DIFF_LINES}]
ini:
- {key: diff_lines, section: colors}
COLOR_DIFF_REMOVE:
name: Color for diff removed display
default: red
description: Defines the color to use when showing removed lines in diffs.
env: [{name: ANSIBLE_COLOR_DIFF_REMOVE}]
ini:
- {key: diff_remove, section: colors}
COLOR_ERROR:
name: Color for error messages
default: red
description: Defines the color to use when emitting error messages.
env: [{name: ANSIBLE_COLOR_ERROR}]
ini:
- {key: error, section: colors}
yaml: {key: colors.error}
COLOR_HIGHLIGHT:
name: Color for highlighting
default: white
description: Defines the color to use for highlighting.
env: [{name: ANSIBLE_COLOR_HIGHLIGHT}]
ini:
- {key: highlight, section: colors}
COLOR_INCLUDED:
name: Color for 'included' task status
default: cyan
description: Defines the color to use when showing 'Included' task status.
env: [{name: ANSIBLE_COLOR_INCLUDED}]
ini:
- {key: included, section: colors}
version_added: '2.18'
COLOR_OK:
name: Color for 'ok' task status
default: green
description: Defines the color to use when showing 'OK' task status.
env: [{name: ANSIBLE_COLOR_OK}]
ini:
- {key: ok, section: colors}
COLOR_SKIP:
name: Color for 'skip' task status
default: cyan
description: Defines the color to use when showing 'Skipped' task status.
env: [{name: ANSIBLE_COLOR_SKIP}]
ini:
- {key: skip, section: colors}
COLOR_UNREACHABLE:
name: Color for 'unreachable' host state
default: bright red
description: Defines the color to use on 'Unreachable' status.
env: [{name: ANSIBLE_COLOR_UNREACHABLE}]
ini:
- {key: unreachable, section: colors}
COLOR_VERBOSE:
name: Color for verbose messages
default: blue
description: Defines the color to use when emitting verbose messages. In other words, those that show with '-v's.
env: [{name: ANSIBLE_COLOR_VERBOSE}]
ini:
- {key: verbose, section: colors}
COLOR_WARN:
name: Color for warning messages
default: bright purple
description: Defines the color to use when emitting warning messages.
env: [{name: ANSIBLE_COLOR_WARN}]
ini:
- {key: warn, section: colors}
COLOR_DOC_MODULE:
name: Color for module name in the ansible-doc output
default: yellow
description: Defines the color to use when emitting a module name in the ansible-doc output.
env: [{name: ANSIBLE_COLOR_DOC_MODULE}]
ini:
- {key: doc_module, section: colors}
version_added: '2.18'
COLOR_DOC_REFERENCE:
name: Color for cross-reference in the ansible-doc output
default: magenta
description: Defines the color to use when emitting cross-reference in the ansible-doc output.
env: [{name: ANSIBLE_COLOR_DOC_REFERENCE}]
ini:
- {key: doc_reference, section: colors}
version_added: '2.18'
COLOR_DOC_LINK:
name: Color for Link in ansible-doc output
default: cyan
description: Defines the color to use when emitting a link in the ansible-doc output.
env: [{name: ANSIBLE_COLOR_DOC_LINK}]
ini:
- {key: doc_link, section: colors}
version_added: '2.18'
COLOR_DOC_DEPRECATED:
name: Color for deprecated value in ansible-doc output
default: magenta
description: Defines the color to use when emitting a deprecated value in the ansible-doc output.
env: [{name: ANSIBLE_COLOR_DOC_DEPRECATED}]
ini:
- {key: doc_deprecated, section: colors}
version_added: '2.18'
COLOR_DOC_CONSTANT:
name: Color for constant in ansible-doc output
default: dark gray
description: Defines the color to use when emitting a constant in the ansible-doc output.
env: [{name: ANSIBLE_COLOR_DOC_CONSTANT}]
ini:
- {key: doc_constant, section: colors}
version_added: '2.18'
COLOR_DOC_PLUGIN:
name: Color for the plugin in ansible-doc output
default: yellow
description: Defines the color to use when emitting a plugin name in the ansible-doc output.
env: [{name: ANSIBLE_COLOR_DOC_PLUGIN}]
ini:
- {key: doc_plugin, section: colors}
version_added: '2.18'
CONNECTION_PASSWORD_FILE:
name: Connection password file
default: ~
description: 'The password file to use for the connection plugin. ``--connection-password-file``.'
env: [{name: ANSIBLE_CONNECTION_PASSWORD_FILE}]
ini:
- {key: connection_password_file, section: defaults}
type: path
version_added: '2.12'
COVERAGE_REMOTE_OUTPUT:
name: Sets the output directory and filename prefix to generate coverage run info.
description:
- Sets the output directory on the remote host to generate coverage reports into.
- Currently only used for remote coverage on PowerShell modules.
- This is for internal use only.
env:
- {name: _ANSIBLE_COVERAGE_REMOTE_OUTPUT}
vars:
- {name: _ansible_coverage_remote_output}
type: str
version_added: '2.9'
COVERAGE_REMOTE_PATHS:
name: Sets the list of paths to run coverage for.
description:
- A list of paths for files on the Ansible controller to run coverage for when executing on the remote host.
- Only files that match the path glob will have their coverage collected.
- Multiple path globs can be specified and are separated by ``:``.
- Currently only used for remote coverage on PowerShell modules.
- This is for internal use only.
default: '*'
env:
- {name: _ANSIBLE_COVERAGE_REMOTE_PATH_FILTER}
type: str
version_added: '2.9'
ACTION_WARNINGS:
name: Toggle action warnings
default: True
description:
- By default, Ansible will issue a warning when received from a task action (module or action plugin).
- These warnings can be silenced by adjusting this setting to False.
env: [{name: ANSIBLE_ACTION_WARNINGS}]
ini:
- {key: action_warnings, section: defaults}
type: boolean
version_added: "2.5"
LOCALHOST_WARNING:
name: Warning when using implicit inventory with only localhost
default: True
description:
- By default, Ansible will issue a warning when there are no hosts in the
inventory.
- These warnings can be silenced by adjusting this setting to False.
env: [{name: ANSIBLE_LOCALHOST_WARNING}]
ini:
- {key: localhost_warning, section: defaults}
type: boolean
version_added: "2.6"
LOG_VERBOSITY:
name: Default log verbosity
description:
- This will set log verbosity if higher than the normal display verbosity, otherwise it will match that.
env: [{name: ANSIBLE_LOG_VERBOSITY}]
ini:
- {key: log_verbosity, section: defaults}
type: int
version_added: "2.17"
INVENTORY_UNPARSED_WARNING:
name: Warning when no inventory files can be parsed, resulting in an implicit inventory with only localhost
default: True
description:
- By default, Ansible will issue a warning when no inventory was loaded and notes that
it will use an implicit localhost-only inventory.
- These warnings can be silenced by adjusting this setting to False.
env: [{name: ANSIBLE_INVENTORY_UNPARSED_WARNING}]
ini:
- {key: inventory_unparsed_warning, section: inventory}
type: boolean
version_added: "2.14"
DOC_FRAGMENT_PLUGIN_PATH:
name: documentation fragment plugins path
default: '{{ ANSIBLE_HOME ~ "/plugins/doc_fragments:/usr/share/ansible/plugins/doc_fragments" }}'
description: Colon-separated paths in which Ansible will search for Documentation Fragments Plugins.
env: [{name: ANSIBLE_DOC_FRAGMENT_PLUGINS}]
ini:
- {key: doc_fragment_plugins, section: defaults}
type: pathspec
DEFAULT_ACTION_PLUGIN_PATH:
name: Action plugins path
default: '{{ ANSIBLE_HOME ~ "/plugins/action:/usr/share/ansible/plugins/action" }}'
description: Colon-separated paths in which Ansible will search for Action Plugins.
env: [{name: ANSIBLE_ACTION_PLUGINS}]
ini:
- {key: action_plugins, section: defaults}
type: pathspec
yaml: {key: plugins.action.path}
DEFAULT_ALLOW_UNSAFE_LOOKUPS:
name: Allow unsafe lookups
default: False
description:
- "When enabled, this option allows lookup plugins (whether used in variables as ``{{lookup('foo')}}`` or as a loop as with_foo)
to return data that is not marked 'unsafe'."
- By default, such data is marked as unsafe to prevent the templating engine from evaluating any jinja2 templating language,
as this could represent a security risk. This option is provided to allow for backward compatibility,
however, users should first consider adding allow_unsafe=True to any lookups that may be expected to contain data that may be run
through the templating engine late.
env: []
ini:
- {key: allow_unsafe_lookups, section: defaults}
type: boolean
version_added: "2.2.3"
deprecated:
why: This option is no longer used in the Ansible Core code base.
version: "2.23"
alternatives: Lookup plugins are responsible for tagging strings containing templates to allow evaluation as a template.
DEFAULT_ASK_PASS:
name: Ask for the login password
default: False
description:
- This controls whether an Ansible playbook should prompt for a login password.
If using SSH keys for authentication, you probably do not need to change this setting.
env: [{name: ANSIBLE_ASK_PASS}]
ini:
- {key: ask_pass, section: defaults}
type: boolean
yaml: {key: defaults.ask_pass}
DEFAULT_ASK_VAULT_PASS:
name: Ask for the vault password(s)
default: False
description:
- This controls whether an Ansible playbook should prompt for a vault password.
env: [{name: ANSIBLE_ASK_VAULT_PASS}]
ini:
- {key: ask_vault_pass, section: defaults}
type: boolean
DEFAULT_BECOME:
name: Enable privilege escalation (become)
default: False
description: Toggles the use of privilege escalation, allowing you to 'become' another user after login.
env: [{name: ANSIBLE_BECOME}]
ini:
- {key: become, section: privilege_escalation}
type: boolean
DEFAULT_BECOME_ASK_PASS:
name: Ask for the privilege escalation (become) password
default: False
description: Toggle to prompt for privilege escalation password.
env: [{name: ANSIBLE_BECOME_ASK_PASS}]
ini:
- {key: become_ask_pass, section: privilege_escalation}
type: boolean
DEFAULT_BECOME_METHOD:
name: Choose privilege escalation method
default: 'sudo'
description: Privilege escalation method to use when `become` is enabled.
env: [{name: ANSIBLE_BECOME_METHOD}]
ini:
- {section: privilege_escalation, key: become_method}
DEFAULT_BECOME_EXE:
name: Choose 'become' executable
default: ~
description: 'executable to use for privilege escalation, otherwise Ansible will depend on PATH.'
env: [{name: ANSIBLE_BECOME_EXE}]
ini:
- {key: become_exe, section: privilege_escalation}
DEFAULT_BECOME_FLAGS:
name: Set 'become' executable options
default: ''
description: Flags to pass to the privilege escalation executable.
env: [{name: ANSIBLE_BECOME_FLAGS}]
ini:
- {key: become_flags, section: privilege_escalation}
BECOME_PLUGIN_PATH:
name: Become plugins path
default: '{{ ANSIBLE_HOME ~ "/plugins/become:/usr/share/ansible/plugins/become" }}'
description: Colon-separated paths in which Ansible will search for Become Plugins.
env: [{name: ANSIBLE_BECOME_PLUGINS}]
ini:
- {key: become_plugins, section: defaults}
type: pathspec
version_added: "2.8"
DEFAULT_BECOME_USER:
# FIXME: should really be blank and make -u passing optional depending on it
name: Set the user you 'become' via privilege escalation
default: root
description: The user your login/remote user 'becomes' when using privilege escalation, most systems will use 'root' when no user is specified.
env: [{name: ANSIBLE_BECOME_USER}]
ini:
- {key: become_user, section: privilege_escalation}
yaml: {key: become.user}
DEFAULT_CACHE_PLUGIN_PATH:
name: Cache Plugins Path
default: '{{ ANSIBLE_HOME ~ "/plugins/cache:/usr/share/ansible/plugins/cache" }}'
description: Colon-separated paths in which Ansible will search for Cache Plugins.
env: [{name: ANSIBLE_CACHE_PLUGINS}]
ini:
- {key: cache_plugins, section: defaults}
type: pathspec
DEFAULT_CALLBACK_PLUGIN_PATH:
name: Callback Plugins Path
default: '{{ ANSIBLE_HOME ~ "/plugins/callback:/usr/share/ansible/plugins/callback" }}'
description: Colon-separated paths in which Ansible will search for Callback Plugins.
env: [{name: ANSIBLE_CALLBACK_PLUGINS}]
ini:
- {key: callback_plugins, section: defaults}
type: pathspec
yaml: {key: plugins.callback.path}
CALLBACKS_ENABLED:
name: Enable callback plugins that require it.
default: []
description:
- "List of enabled callbacks, not all callbacks need enabling,
but many of those shipped with Ansible do as we don't want them activated by default."
env:
- name: ANSIBLE_CALLBACKS_ENABLED
version_added: '2.11'
ini:
- key: callbacks_enabled
section: defaults
version_added: '2.11'
type: list
DEFAULT_CLICONF_PLUGIN_PATH:
name: Cliconf Plugins Path
default: '{{ ANSIBLE_HOME ~ "/plugins/cliconf:/usr/share/ansible/plugins/cliconf" }}'
description: Colon-separated paths in which Ansible will search for Cliconf Plugins.
env: [{name: ANSIBLE_CLICONF_PLUGINS}]
ini:
- {key: cliconf_plugins, section: defaults}
type: pathspec
DEFAULT_CONNECTION_PLUGIN_PATH:
name: Connection Plugins Path
default: '{{ ANSIBLE_HOME ~ "/plugins/connection:/usr/share/ansible/plugins/connection" }}'
description: Colon-separated paths in which Ansible will search for Connection Plugins.
env: [{name: ANSIBLE_CONNECTION_PLUGINS}]
ini:
- {key: connection_plugins, section: defaults}
type: pathspec
yaml: {key: plugins.connection.path}
DEFAULT_DEBUG:
name: Debug mode
default: False
description:
- "Toggles debug output in Ansible. This is *very* verbose and can hinder
multiprocessing. Debug output can also include secret information
despite no_log settings being enabled, which means debug mode should not be used in
production."
env: [{name: ANSIBLE_DEBUG}]
ini:
- {key: debug, section: defaults}
type: boolean
DEFAULT_EXECUTABLE:
name: Target shell executable
default: /bin/sh
description:
- "This indicates the command to use to spawn a shell under, which is required for Ansible's execution needs on a target.
Users may need to change this in rare instances when shell usage is constrained, but in most cases, it may be left as is."
env: [{name: ANSIBLE_EXECUTABLE}]
ini:
- {key: executable, section: defaults}
DEFAULT_FILTER_PLUGIN_PATH:
name: Jinja2 Filter Plugins Path
default: '{{ ANSIBLE_HOME ~ "/plugins/filter:/usr/share/ansible/plugins/filter" }}'
description: Colon-separated paths in which Ansible will search for Jinja2 Filter Plugins.
env: [{name: ANSIBLE_FILTER_PLUGINS}]
ini:
- {key: filter_plugins, section: defaults}
type: pathspec
DEFAULT_FORCE_HANDLERS:
name: Force handlers to run after failure
default: False
description:
- This option controls if notified handlers run on a host even if a failure occurs on that host.
- When false, the handlers will not run if a failure has occurred on a host.
- This can also be set per play or on the command line. See Handlers and Failure for more details.
env: [{name: ANSIBLE_FORCE_HANDLERS}]
ini:
- {key: force_handlers, section: defaults}
type: boolean
version_added: "1.9.1"
DEFAULT_FORKS:
name: Number of task forks
default: 5
description: Maximum number of forks Ansible will use to execute tasks on target hosts.
env: [{name: ANSIBLE_FORKS}]
ini:
- {key: forks, section: defaults}
type: integer
DEFAULT_GATHERING:
name: Gathering behaviour
default: 'implicit'
description:
- This setting controls the default policy of fact gathering (facts discovered about remote systems).
- "This option can be useful for those wishing to save fact gathering time. Both 'smart' and 'explicit' will use the cache plugin."
env: [{name: ANSIBLE_GATHERING}]
ini:
- key: gathering
section: defaults
version_added: "1.6"
choices:
implicit: "the cache plugin will be ignored and facts will be gathered per play unless 'gather_facts: False' is set."
explicit: facts will not be gathered unless directly requested in the play.
smart: each new host that has no facts discovered will be scanned, but if the same host is addressed in multiple plays it will not be contacted again in the run.
DEFAULT_HASH_BEHAVIOUR:
name: Hash merge behaviour
default: replace
type: string
choices:
replace: Any variable that is defined more than once is overwritten using the order from variable precedence rules (highest wins).
merge: Any dictionary variable will be recursively merged with new definitions across the different variable definition sources.
description:
- This setting controls how duplicate definitions of dictionary variables (aka hash, map, associative array) are handled in Ansible.
- This does not affect variables whose values are scalars (integers, strings) or arrays.
- "**WARNING**, changing this setting is not recommended as this is fragile and makes your content (plays, roles, collections) nonportable,
leading to continual confusion and misuse. Don't change this setting unless you think you have an absolute need for it."
- We recommend avoiding reusing variable names and relying on the ``combine`` filter and ``vars`` and ``varnames`` lookups
to create merged versions of the individual variables. In our experience, this is rarely needed and is a sign that too much
complexity has been introduced into the data structures and plays.
- For some uses you can also look into custom vars_plugins to merge on input, even substituting the default ``host_group_vars``
that is in charge of parsing the ``host_vars/`` and ``group_vars/`` directories. Most users of this setting are only interested in inventory scope,
but the setting itself affects all sources and makes debugging even harder.
- All playbooks and roles in the official examples repos assume the default for this setting.
- Changing the setting to ``merge`` applies across variable sources, but many sources will internally still overwrite the variables.
For example ``include_vars`` will dedupe variables internally before updating Ansible, with 'last defined' overwriting previous definitions in same file.
- The Ansible project recommends you **avoid ``merge`` for new projects.**
- It is the intention of the Ansible developers to eventually deprecate and remove this setting, but it is being kept as some users do heavily rely on it.
New projects should **avoid 'merge'**.
env: [{name: ANSIBLE_HASH_BEHAVIOUR}]
ini:
- {key: hash_behaviour, section: defaults}
DEFAULT_HOST_LIST:
name: Inventory Source
default: [/etc/ansible/hosts]
description: Comma-separated list of Ansible inventory sources
env:
- name: ANSIBLE_INVENTORY
expand_relative_paths: True
ini:
- key: inventory
section: defaults
type: pathlist
yaml: {key: defaults.inventory}
DEFAULT_HTTPAPI_PLUGIN_PATH:
name: HttpApi Plugins Path
default: '{{ ANSIBLE_HOME ~ "/plugins/httpapi:/usr/share/ansible/plugins/httpapi" }}'
description: Colon-separated paths in which Ansible will search for HttpApi Plugins.
env: [{name: ANSIBLE_HTTPAPI_PLUGINS}]
ini:
- {key: httpapi_plugins, section: defaults}
type: pathspec
DEFAULT_INTERNAL_POLL_INTERVAL:
name: Internal poll interval
default: 0.001
env: []
ini:
- {key: internal_poll_interval, section: defaults}
type: float
version_added: "2.2"
description:
- This sets the interval (in seconds) of Ansible internal processes polling each other.
Lower values improve performance with large playbooks at the expense of extra CPU load.
Higher values are more suitable for Ansible usage in automation scenarios
when UI responsiveness is not required but CPU usage might be a concern.
- "The default corresponds to the value hardcoded in Ansible <= 2.1"
DEFAULT_INVENTORY_PLUGIN_PATH:
name: Inventory Plugins Path
default: '{{ ANSIBLE_HOME ~ "/plugins/inventory:/usr/share/ansible/plugins/inventory" }}'
description: Colon-separated paths in which Ansible will search for Inventory Plugins.
env: [{name: ANSIBLE_INVENTORY_PLUGINS}]
ini:
- {key: inventory_plugins, section: defaults}
type: pathspec
DEFAULT_JINJA2_EXTENSIONS:
name: Enabled Jinja2 extensions
default: []
type: list
description:
- This is a developer-specific feature that allows enabling additional Jinja2 extensions.
- "See the Jinja2 documentation for details. If you do not know what these do, you probably don't need to change this setting :)"
env: [{name: ANSIBLE_JINJA2_EXTENSIONS}]
ini:
- {key: jinja2_extensions, section: defaults}
deprecated:
why: Jinja2 extensions have been deprecated
version: "2.23"
alternatives: Ansible-supported Jinja plugins (tests, filters, lookups)
DEFAULT_JINJA2_NATIVE:
name: Use Jinja2's NativeEnvironment for templating
default: True
description: This option preserves variable types during template operations.
env: [{name: ANSIBLE_JINJA2_NATIVE}]
ini:
- {key: jinja2_native, section: defaults}
type: boolean
yaml: {key: jinja2_native}
version_added: 2.7
deprecated:
why: This option is no longer used in the Ansible Core code base.
version: "2.23"
alternatives: Jinja2 native mode is now the default and only option.
DEFAULT_KEEP_REMOTE_FILES:
name: Keep remote files
default: False
description:
- Enables/disables the cleaning up of the temporary files Ansible used to execute the tasks on the remote.
- If this option is enabled it will disable ``ANSIBLE_PIPELINING``.
env: [{name: ANSIBLE_KEEP_REMOTE_FILES}]
ini:
- {key: keep_remote_files, section: defaults}
type: boolean
DEFAULT_LIBVIRT_LXC_NOSECLABEL:
name: No security label on Lxc
default: False
description:
- "This setting causes libvirt to connect to LXC containers by passing ``--noseclabel`` parameter to ``virsh`` command.
This is necessary when running on systems which do not have SELinux."
env:
- name: ANSIBLE_LIBVIRT_LXC_NOSECLABEL
ini:
- {key: libvirt_lxc_noseclabel, section: selinux}
type: boolean
version_added: "2.1"
deprecated:
why: This option was moved to the plugin itself
version: "2.22"
alternatives: Use the option from the plugin itself.
DEFAULT_LOAD_CALLBACK_PLUGINS:
name: Load callbacks for adhoc
default: False
description:
- Controls whether callback plugins are loaded when running /usr/bin/ansible.
This may be used to log activity from the command line, send notifications, and so on.
Callback plugins are always loaded for ``ansible-playbook``.
env: [{name: ANSIBLE_LOAD_CALLBACK_PLUGINS}]
ini:
- {key: bin_ansible_callbacks, section: defaults}
type: boolean
version_added: "1.8"
DEFAULT_LOCAL_TMP:
name: Controller temporary directory
default: '{{ ANSIBLE_HOME ~ "/tmp" }}'
description: Temporary directory for Ansible to use on the controller.
env: [{name: ANSIBLE_LOCAL_TEMP}]
ini:
- {key: local_tmp, section: defaults}
type: tmppath
DEFAULT_LOG_PATH:
name: Ansible log file path
default: ~
description:
- File to which Ansible will log on the controller.
- When not set the logging is disabled.
env: [{name: ANSIBLE_LOG_PATH}]
ini:
- {key: log_path, section: defaults}
type: path
DEFAULT_LOG_FILTER:
name: Name filters for python logger
default: []
description: List of logger names to filter out of the log file.
env: [{name: ANSIBLE_LOG_FILTER}]
ini:
- {key: log_filter, section: defaults}
type: list
DEFAULT_LOOKUP_PLUGIN_PATH:
name: Lookup Plugins Path
description: Colon-separated paths in which Ansible will search for Lookup Plugins.
default: '{{ ANSIBLE_HOME ~ "/plugins/lookup:/usr/share/ansible/plugins/lookup" }}'
env: [{name: ANSIBLE_LOOKUP_PLUGINS}]
ini:
- {key: lookup_plugins, section: defaults}
type: pathspec
yaml: {key: defaults.lookup_plugins}
DEFAULT_MANAGED_STR:
name: Ansible managed
default: 'Ansible managed'
description: Sets the macro for the 'ansible_managed' variable available for :ref:`ansible_collections.ansible.builtin.template_module` and :ref:`ansible_collections.ansible.windows.win_template_module`. This is only relevant to those two modules.
env: []
ini:
- {key: ansible_managed, section: defaults}
yaml: {key: defaults.ansible_managed}
DEFAULT_MODULE_ARGS:
name: Adhoc default arguments
default: ~
description:
- This sets the default arguments to pass to the ``ansible`` adhoc binary if no ``-a`` is specified.
env: [{name: ANSIBLE_MODULE_ARGS}]
ini:
- {key: module_args, section: defaults}
DEFAULT_MODULE_COMPRESSION:
name: Python module compression
default: ZIP_DEFLATED
description: Compression scheme to use when transferring Python modules to the target.
env: []
ini:
- {key: module_compression, section: defaults}
vars:
- name: ansible_module_compression
DEFAULT_MODULE_NAME:
name: Default adhoc module
default: command
description: "Module to use with the ``ansible`` AdHoc command, if none is specified via ``-m``."
env: []
ini:
- {key: module_name, section: defaults}
DEFAULT_MODULE_PATH:
name: Modules Path
description: Colon-separated paths in which Ansible will search for Modules.
default: '{{ ANSIBLE_HOME ~ "/plugins/modules:/usr/share/ansible/plugins/modules" }}'
env: [{name: ANSIBLE_LIBRARY}]
ini:
- {key: library, section: defaults}
type: pathspec
DEFAULT_MODULE_UTILS_PATH:
name: Module Utils Path
description: Colon-separated paths in which Ansible will search for Module utils files, which are shared by modules.
default: '{{ ANSIBLE_HOME ~ "/plugins/module_utils:/usr/share/ansible/plugins/module_utils" }}'
env: [{name: ANSIBLE_MODULE_UTILS}]
ini:
- {key: module_utils, section: defaults}
type: pathspec
DEFAULT_NETCONF_PLUGIN_PATH:
name: Netconf Plugins Path
default: '{{ ANSIBLE_HOME ~ "/plugins/netconf:/usr/share/ansible/plugins/netconf" }}'
description: Colon-separated paths in which Ansible will search for Netconf Plugins.
env: [{name: ANSIBLE_NETCONF_PLUGINS}]
ini:
- {key: netconf_plugins, section: defaults}
type: pathspec
DEFAULT_NO_LOG:
name: No log
default: False
description: "Toggle Ansible's display and logging of task details, mainly used to avoid security disclosures."
env: [{name: ANSIBLE_NO_LOG}]
ini:
- {key: no_log, section: defaults}
type: boolean
DEFAULT_NO_TARGET_SYSLOG:
name: No syslog on target
default: False
description:
- Toggle Ansible logging to syslog on the target when it executes tasks. On Windows hosts, this will disable a newer
style PowerShell modules from writing to the event log.
env: [{name: ANSIBLE_NO_TARGET_SYSLOG}]
ini:
- {key: no_target_syslog, section: defaults}
vars:
- name: ansible_no_target_syslog
version_added: '2.10'
type: boolean
yaml: {key: defaults.no_target_syslog}
DEFAULT_NULL_REPRESENTATION:
name: Represent a null
default: ~
description: What templating should return as a 'null' value. When not set it will let Jinja2 decide.
env: [{name: ANSIBLE_NULL_REPRESENTATION}]
ini:
- {key: null_representation, section: defaults}
type: raw
deprecated:
why: This option is no longer used in the Ansible Core code base.
version: "2.23"
alternatives: There is no alternative at the moment. A different mechanism would have to be implemented in the current code base.
DEFAULT_POLL_INTERVAL:
name: Async poll interval
default: 15
description:
- For asynchronous tasks in Ansible (covered in Asynchronous Actions and Polling),
this is how often to check back on the status of those tasks when an explicit poll interval is not supplied.
The default is a reasonably moderate 15 seconds which is a tradeoff between checking in frequently and
providing a quick turnaround when something may have completed.
env: [{name: ANSIBLE_POLL_INTERVAL}]
ini:
- {key: poll_interval, section: defaults}
type: integer
DEFAULT_PRIVATE_KEY_FILE:
name: Private key file
default: ~
description:
- Option for connections using a certificate or key file to authenticate, rather than an agent or passwords,
you can set the default value here to avoid re-specifying ``--private-key`` with every invocation.
env: [{name: ANSIBLE_PRIVATE_KEY_FILE}]
ini:
- {key: private_key_file, section: defaults}
type: path
DEFAULT_PRIVATE_ROLE_VARS:
name: Private role variables
default: False
description:
- By default, imported roles publish their variables to the play and other roles, this setting can avoid that.
- This was introduced as a way to reset role variables to default values if a role is used more than once
in a playbook.
- Starting in version '2.17' M(ansible.builtin.include_roles) and M(ansible.builtin.import_roles) can
individually override this via the C(public) parameter.
- Included roles only make their variables public at execution, unlike imported roles which happen at playbook compile time.
env: [{name: ANSIBLE_PRIVATE_ROLE_VARS}]
ini:
- {key: private_role_vars, section: defaults}
type: boolean
yaml: {key: defaults.private_role_vars}
DEFAULT_REMOTE_PORT:
name: Remote port
default: ~
description: Port to use in remote connections, when blank it will use the connection plugin default.
env: [{name: ANSIBLE_REMOTE_PORT}]
ini:
- {key: remote_port, section: defaults}
type: integer
yaml: {key: defaults.remote_port}
DEFAULT_REMOTE_USER:
name: Login/Remote User
description:
- Sets the login user for the target machines
- "When blank it uses the connection plugin's default, normally the user currently executing Ansible."
env: [{name: ANSIBLE_REMOTE_USER}]
ini:
- {key: remote_user, section: defaults}
DEFAULT_ROLES_PATH:
name: Roles path
default: '{{ ANSIBLE_HOME ~ "/roles:/usr/share/ansible/roles:/etc/ansible/roles" }}'
description: Colon-separated paths in which Ansible will search for Roles.
env: [{name: ANSIBLE_ROLES_PATH}]
expand_relative_paths: True
ini:
- {key: roles_path, section: defaults}
type: pathspec
yaml: {key: defaults.roles_path}
DEFAULT_SELINUX_SPECIAL_FS:
name: Problematic file systems
default: [fuse, nfs, vboxsf, ramfs, 9p, vfat]
description:
- "Some filesystems do not support safe operations and/or return inconsistent errors,
this setting makes Ansible 'tolerate' those in the list without causing fatal errors."
- Data corruption may occur and writes are not always verified when a filesystem is in the list.
env:
- name: ANSIBLE_SELINUX_SPECIAL_FS
version_added: "2.9"
ini:
- {key: special_context_filesystems, section: selinux}
type: list
DEFAULT_STDOUT_CALLBACK:
name: Main display callback plugin
default: default
description:
- "Set the main callback used to display Ansible output. You can only have one at a time."
- You can have many other callbacks, but just one can be in charge of stdout.
- See :ref:`callback_plugins` for a list of available options.
env: [{name: ANSIBLE_STDOUT_CALLBACK}]
ini:
- {key: stdout_callback, section: defaults}
EDITOR:
name: editor application to use
default: vi
description:
- for the cases in which Ansible needs to return a file within an editor, this chooses the application to use.
ini:
- section: defaults
key: editor
version_added: '2.15'
env:
- name: ANSIBLE_EDITOR
version_added: '2.15'
- name: EDITOR
ENABLE_TASK_DEBUGGER:
name: Whether to enable the task debugger
default: False
description:
- Whether or not to enable the task debugger, this previously was done as a strategy plugin.
- Now all strategy plugins can inherit this behavior. The debugger defaults to activating when
- a task is failed on unreachable. Use the debugger keyword for more flexibility.
type: boolean
env: [{name: ANSIBLE_ENABLE_TASK_DEBUGGER}]
ini:
- {key: enable_task_debugger, section: defaults}
version_added: "2.5"
TASK_DEBUGGER_IGNORE_ERRORS:
name: Whether a failed task with ignore_errors=True will still invoke the debugger
default: True
description:
- This option defines whether the task debugger will be invoked on a failed task when ignore_errors=True
is specified.
- True specifies that the debugger will honor ignore_errors, and False will not honor ignore_errors.
type: boolean
env: [{name: ANSIBLE_TASK_DEBUGGER_IGNORE_ERRORS}]
ini:
- {key: task_debugger_ignore_errors, section: defaults}
version_added: "2.7"
DEFAULT_STRATEGY:
name: Implied strategy
default: 'linear'
description: Set the default strategy used for plays.
env: [{name: ANSIBLE_STRATEGY}]
ini:
- {key: strategy, section: defaults}
version_added: "2.3"
DEFAULT_STRATEGY_PLUGIN_PATH:
name: Strategy Plugins Path
description: Colon-separated paths in which Ansible will search for Strategy Plugins.
default: '{{ ANSIBLE_HOME ~ "/plugins/strategy:/usr/share/ansible/plugins/strategy" }}'
env: [{name: ANSIBLE_STRATEGY_PLUGINS}]
ini:
- {key: strategy_plugins, section: defaults}
type: pathspec
DEFAULT_SU:
default: False
description: 'Toggle the use of "su" for tasks.'
env: [{name: ANSIBLE_SU}]
ini:
- {key: su, section: defaults}
type: boolean
yaml: {key: defaults.su}
DEFAULT_SYSLOG_FACILITY:
name: syslog facility
default: LOG_USER
description: Syslog facility to use when Ansible logs to the remote target.
env: [{name: ANSIBLE_SYSLOG_FACILITY}]
ini:
- {key: syslog_facility, section: defaults}
DEFAULT_TERMINAL_PLUGIN_PATH:
name: Terminal Plugins Path
default: '{{ ANSIBLE_HOME ~ "/plugins/terminal:/usr/share/ansible/plugins/terminal" }}'
description: Colon-separated paths in which Ansible will search for Terminal Plugins.
env: [{name: ANSIBLE_TERMINAL_PLUGINS}]
ini:
- {key: terminal_plugins, section: defaults}
type: pathspec
DEFAULT_TEST_PLUGIN_PATH:
name: Jinja2 Test Plugins Path
description: Colon-separated paths in which Ansible will search for Jinja2 Test Plugins.
default: '{{ ANSIBLE_HOME ~ "/plugins/test:/usr/share/ansible/plugins/test" }}'
env: [{name: ANSIBLE_TEST_PLUGINS}]
ini:
- {key: test_plugins, section: defaults}
type: pathspec
DEFAULT_TIMEOUT:
name: Connection timeout
default: 10
description: This is the default timeout for connection plugins to use.
env: [{name: ANSIBLE_TIMEOUT}]
ini:
- {key: timeout, section: defaults}
type: integer
DEFAULT_TRANSPORT:
name: Connection plugin
default: ssh
description:
- Can be any connection plugin available to your ansible installation.
- There is also a (DEPRECATED) special 'smart' option, that will toggle between 'ssh' and 'paramiko' depending on controller OS and ssh versions.
env: [{name: ANSIBLE_TRANSPORT}]
ini:
- {key: transport, section: defaults}
DEFAULT_UNDEFINED_VAR_BEHAVIOR:
name: Jinja2 fail on undefined
default: True
version_added: "1.3"
description:
- When True, this causes ansible templating to fail steps that reference variable names that are likely typoed.
- "Otherwise, any '{{ template_expression }}' that contains undefined variables will be rendered in a template or ansible action line exactly as written."
env: [{name: ANSIBLE_ERROR_ON_UNDEFINED_VARS}]
ini:
- {key: error_on_undefined_vars, section: defaults}
type: boolean
deprecated:
why: This option is no longer used in the Ansible Core code base.
version: "2.23"
alternatives: There is no alternative at the moment. A different mechanism would have to be implemented in the current code base.
DEFAULT_VARS_PLUGIN_PATH:
name: Vars Plugins Path
default: '{{ ANSIBLE_HOME ~ "/plugins/vars:/usr/share/ansible/plugins/vars" }}'
description: Colon-separated paths in which Ansible will search for Vars Plugins.
env: [{name: ANSIBLE_VARS_PLUGINS}]
ini:
- {key: vars_plugins, section: defaults}
type: pathspec
DEFAULT_VAULT_ID_MATCH:
name: Force vault id match
default: False
description: 'If true, decrypting vaults with a vault id will only try the password from the matching vault-id.'
env: [{name: ANSIBLE_VAULT_ID_MATCH}]
ini:
- {key: vault_id_match, section: defaults}
yaml: {key: defaults.vault_id_match}
DEFAULT_VAULT_IDENTITY:
name: Vault id label
default: default
description: 'The label to use for the default vault id label in cases where a vault id label is not provided.'
env: [{name: ANSIBLE_VAULT_IDENTITY}]
ini:
- {key: vault_identity, section: defaults}
yaml: {key: defaults.vault_identity}
VAULT_ENCRYPT_SALT:
name: Vault salt to use for encryption
default: ~
description: 'The salt to use for the vault encryption. If it is not provided, a random salt will be used.'
env: [{name: ANSIBLE_VAULT_ENCRYPT_SALT}]
ini:
- {key: vault_encrypt_salt, section: defaults}
version_added: '2.15'
DEFAULT_VAULT_ENCRYPT_IDENTITY:
name: Vault id to use for encryption
description: 'The vault_id to use for encrypting by default. If multiple vault_ids are provided, this specifies which to use for encryption. The ``--encrypt-vault-id`` CLI option overrides the configured value.'
env: [{name: ANSIBLE_VAULT_ENCRYPT_IDENTITY}]
ini:
- {key: vault_encrypt_identity, section: defaults}
yaml: {key: defaults.vault_encrypt_identity}
DEFAULT_VAULT_IDENTITY_LIST:
name: Default vault ids
default: []
description: 'A list of vault-ids to use by default. Equivalent to multiple ``--vault-id`` args. Vault-ids are tried in order.'
env: [{name: ANSIBLE_VAULT_IDENTITY_LIST}]
ini:
- {key: vault_identity_list, section: defaults}
type: list
yaml: {key: defaults.vault_identity_list}
DEFAULT_VAULT_PASSWORD_FILE:
name: Vault password file
default: ~
description:
- 'The vault password file to use. Equivalent to ``--vault-password-file`` or ``--vault-id``.'
- If executable, it will be run and the resulting stdout will be used as the password.
env: [{name: ANSIBLE_VAULT_PASSWORD_FILE}]
ini:
- {key: vault_password_file, section: defaults}
type: path
yaml: {key: defaults.vault_password_file}
DEFAULT_VERBOSITY:
name: Verbosity
default: 0
description: Sets the default verbosity, equivalent to the number of ``-v`` passed in the command line.
env: [{name: ANSIBLE_VERBOSITY}]
ini:
- {key: verbosity, section: defaults}
type: integer
DEPRECATION_WARNINGS:
name: Deprecation messages
default: True
description: "Toggle to control the showing of deprecation warnings"
env: [{name: ANSIBLE_DEPRECATION_WARNINGS}]
ini:
- {key: deprecation_warnings, section: defaults}
type: boolean
vars:
- name: ansible_deprecation_warnings
version_added: '2.19'
DEVEL_WARNING:
name: Running devel warning
default: True
description: Toggle to control showing warnings related to running devel.
env: [{name: ANSIBLE_DEVEL_WARNING}]
ini:
- {key: devel_warning, section: defaults}
type: boolean
DIFF_ALWAYS:
name: Show differences
default: False
description: Configuration toggle to tell modules to show differences when in 'changed' status, equivalent to ``--diff``.
env: [{name: ANSIBLE_DIFF_ALWAYS}]
ini:
- {key: always, section: diff}
type: bool
DIFF_CONTEXT:
name: Difference context
default: 3
description: Number of lines of context to show when displaying the differences between files.
env: [{name: ANSIBLE_DIFF_CONTEXT}]
ini:
- {key: context, section: diff}
type: integer
DISPLAY_ARGS_TO_STDOUT:
name: Show task arguments
default: False
description:
- "Normally ``ansible-playbook`` will print a header for each task that is run.
These headers will contain the name: field from the task if you specified one.
If you didn't then ``ansible-playbook`` uses the task's action to help you tell which task is presently running.
Sometimes you run many of the same action and so you want more information about the task to differentiate it from others of the same action.
If you set this variable to True in the config then ``ansible-playbook`` will also include the task's arguments in the header."
- "This setting defaults to False because there is a chance that you have sensitive values in your parameters and
you do not want those to be printed."
- "If you set this to True you should be sure that you have secured your environment's stdout
(no one can shoulder surf your screen and you aren't saving stdout to an insecure file) or
made sure that all of your playbooks explicitly added the ``no_log: True`` parameter to tasks that have sensitive values
:ref:`keep_secret_data` for more information."
env: [{name: ANSIBLE_DISPLAY_ARGS_TO_STDOUT}]
ini:
- {key: display_args_to_stdout, section: defaults}
type: boolean
version_added: "2.1"
DISPLAY_SKIPPED_HOSTS:
name: Show skipped results
default: True
description: "Toggle to control displaying skipped task/host entries in a task in the default callback."
env:
- name: ANSIBLE_DISPLAY_SKIPPED_HOSTS
ini:
- {key: display_skipped_hosts, section: defaults}
type: boolean
DISPLAY_TRACEBACK:
name: Control traceback display
default: [never]
description: When to include tracebacks in extended error messages
env:
- name: ANSIBLE_DISPLAY_TRACEBACK
ini:
- {key: display_traceback, section: defaults}
type: list
choices:
- error
- warning
- deprecated
- always
- never
version_added: "2.19"
DOCSITE_ROOT_URL:
name: Root docsite URL
default: https://docs.ansible.com/ansible-core/
description: Root docsite URL used to generate docs URLs in warning/error text;
must be an absolute URL with a valid scheme and trailing slash.
ini:
- {key: docsite_root_url, section: defaults}
version_added: "2.8"
DUPLICATE_YAML_DICT_KEY:
name: Controls ansible behaviour when finding duplicate keys in YAML.
default: warn
description:
- By default, Ansible will issue a warning when a duplicate dict key is encountered in YAML.
- These warnings can be silenced by adjusting this setting to False.
env: [{name: ANSIBLE_DUPLICATE_YAML_DICT_KEY}]
ini:
- {key: duplicate_dict_key, section: defaults}
type: string
choices: &basic_error2
error: issue a 'fatal' error and stop the play
warn: issue a warning but continue
ignore: just continue silently
version_added: "2.9"
ERROR_ON_MISSING_HANDLER:
name: Missing handler error
default: True
description: "Toggle to allow missing handlers to become a warning instead of an error when notifying."
env: [{name: ANSIBLE_ERROR_ON_MISSING_HANDLER}]
ini:
- {key: error_on_missing_handler, section: defaults}
type: boolean
CONNECTION_FACTS_MODULES:
name: Map of connections to fact modules
default:
# use ansible.legacy names on unqualified facts modules to allow library/ overrides
asa: ansible.legacy.asa_facts
cisco.asa.asa: cisco.asa.asa_facts
eos: ansible.legacy.eos_facts
arista.eos.eos: arista.eos.eos_facts
frr: ansible.legacy.frr_facts
frr.frr.frr: frr.frr.frr_facts
ios: ansible.legacy.ios_facts
cisco.ios.ios: cisco.ios.ios_facts
iosxr: ansible.legacy.iosxr_facts
cisco.iosxr.iosxr: cisco.iosxr.iosxr_facts
junos: ansible.legacy.junos_facts
junipernetworks.junos.junos: junipernetworks.junos.junos_facts
nxos: ansible.legacy.nxos_facts
cisco.nxos.nxos: cisco.nxos.nxos_facts
vyos: ansible.legacy.vyos_facts
vyos.vyos.vyos: vyos.vyos.vyos_facts
exos: ansible.legacy.exos_facts
extreme.exos.exos: extreme.exos.exos_facts
slxos: ansible.legacy.slxos_facts
extreme.slxos.slxos: extreme.slxos.slxos_facts
voss: ansible.legacy.voss_facts
extreme.voss.voss: extreme.voss.voss_facts
ironware: ansible.legacy.ironware_facts
community.network.ironware: community.network.ironware_facts
description: "Which modules to run during a play's fact gathering stage based on connection"
type: dict
FACTS_MODULES:
name: Gather Facts Modules
default:
- smart
description:
- "Which modules to run during a play's fact gathering stage, using the default of 'smart' will try to figure it out based on connection type."
- "If adding your own modules but you still want to use the default Ansible facts, you will want to include 'setup'
or corresponding network module to the list (if you add 'smart', Ansible will also figure it out)."
- "This does not affect explicit calls to the 'setup' module, but does always affect the 'gather_facts' action (implicit or explicit)."
env: [{name: ANSIBLE_FACTS_MODULES}]
ini:
- {key: facts_modules, section: defaults}
type: list
vars:
- name: ansible_facts_modules
GALAXY_IGNORE_CERTS:
name: Galaxy validate certs
description:
- If set to yes, ansible-galaxy will not validate TLS certificates.
This can be useful for testing against a server with a self-signed certificate.
env: [{name: ANSIBLE_GALAXY_IGNORE}]
ini:
- {key: ignore_certs, section: galaxy}
type: boolean
GALAXY_SERVER_TIMEOUT:
name: Default timeout to use for API calls
description:
- The default timeout for Galaxy API calls. Galaxy servers that don't configure a specific timeout will fall back to this value.
env: [{name: ANSIBLE_GALAXY_SERVER_TIMEOUT}]
default: 60
ini:
- {key: server_timeout, section: galaxy}
type: int
GALAXY_ROLE_SKELETON:
name: Galaxy role skeleton directory
description: Role skeleton directory to use as a template for the ``init`` action in ``ansible-galaxy``/``ansible-galaxy role``, same as ``--role-skeleton``.
env: [{name: ANSIBLE_GALAXY_ROLE_SKELETON}]
ini:
- {key: role_skeleton, section: galaxy}
type: path
GALAXY_ROLE_SKELETON_IGNORE:
name: Galaxy role skeleton ignore
default: ["^.git$", "^.*/.git_keep$"]
description: patterns of files to ignore inside a Galaxy role or collection skeleton directory.
env: [{name: ANSIBLE_GALAXY_ROLE_SKELETON_IGNORE}]
ini:
- {key: role_skeleton_ignore, section: galaxy}
type: list
GALAXY_COLLECTION_SKELETON:
name: Galaxy collection skeleton directory
description: Collection skeleton directory to use as a template for the ``init`` action in ``ansible-galaxy collection``, same as ``--collection-skeleton``.
env: [{name: ANSIBLE_GALAXY_COLLECTION_SKELETON}]
ini:
- {key: collection_skeleton, section: galaxy}
type: path
GALAXY_COLLECTION_SKELETON_IGNORE:
name: Galaxy collection skeleton ignore
default: ["^.git$", "^.*/.git_keep$"]
description: patterns of files to ignore inside a Galaxy collection skeleton directory.
env: [{name: ANSIBLE_GALAXY_COLLECTION_SKELETON_IGNORE}]
ini:
- {key: collection_skeleton_ignore, section: galaxy}
type: list
GALAXY_COLLECTIONS_PATH_WARNING:
name: "ansible-galaxy collection install collections path warnings"
description: "whether ``ansible-galaxy collection install`` should warn about ``--collections-path`` missing from configured :ref:`collections_paths`."
default: true
type: bool
env: [{name: ANSIBLE_GALAXY_COLLECTIONS_PATH_WARNING}]
ini:
- {key: collections_path_warning, section: galaxy}
version_added: "2.16"
GALAXY_SERVER:
default: https://galaxy.ansible.com
description: "URL to prepend when roles don't specify the full URI, assume they are referencing this server as the source."
env: [{name: ANSIBLE_GALAXY_SERVER}]
ini:
- {key: server, section: galaxy}
yaml: {key: galaxy.server}
GALAXY_SERVER_LIST:
description:
- A list of Galaxy servers to use when installing a collection.
- The value corresponds to the config ini header ``[galaxy_server.{{item}}]`` which defines the server details.
- 'See :ref:`galaxy_server_config` for more details on how to define a Galaxy server.'
- The order of servers in this list is used as the order in which a collection is resolved.
- Setting this config option will ignore the :ref:`galaxy_server` config option.
env: [{name: ANSIBLE_GALAXY_SERVER_LIST}]
ini:
- {key: server_list, section: galaxy}
type: list
version_added: "2.9"
GALAXY_TOKEN_PATH:
default: '{{ ANSIBLE_HOME ~ "/galaxy_token" }}'
description: "Local path to galaxy access token file"
env: [{name: ANSIBLE_GALAXY_TOKEN_PATH}]
ini:
- {key: token_path, section: galaxy}
type: path
version_added: "2.9"
GALAXY_DISPLAY_PROGRESS:
default: ~
description:
- Some steps in ``ansible-galaxy`` display a progress wheel which can cause issues on certain displays or when
outputting the stdout to a file.
- This config option controls whether the display wheel is shown or not.
- The default is to show the display wheel if stdout has a tty.
env: [{name: ANSIBLE_GALAXY_DISPLAY_PROGRESS}]
ini:
- {key: display_progress, section: galaxy}
type: bool
version_added: "2.10"
GALAXY_CACHE_DIR:
default: '{{ ANSIBLE_HOME ~ "/galaxy_cache" }}'
description:
- The directory that stores cached responses from a Galaxy server.
- This is only used by the ``ansible-galaxy collection install`` and ``download`` commands.
- Cache files inside this dir will be ignored if they are world writable.
env:
- name: ANSIBLE_GALAXY_CACHE_DIR
ini:
- section: galaxy
key: cache_dir
type: path
version_added: '2.11'
GALAXY_DISABLE_GPG_VERIFY:
default: false
type: bool
env:
- name: ANSIBLE_GALAXY_DISABLE_GPG_VERIFY
ini:
- section: galaxy
key: disable_gpg_verify
description:
- Disable GPG signature verification during collection installation.
version_added: '2.13'
GALAXY_GPG_KEYRING:
type: path
env:
- name: ANSIBLE_GALAXY_GPG_KEYRING
ini:
- section: galaxy
key: gpg_keyring
description:
- Configure the keyring used for GPG signature verification during collection installation and verification.
version_added: '2.13'
GALAXY_IGNORE_INVALID_SIGNATURE_STATUS_CODES:
type: list
env:
- name: ANSIBLE_GALAXY_IGNORE_SIGNATURE_STATUS_CODES
ini:
- section: galaxy
key: ignore_signature_status_codes
description:
- A list of GPG status codes to ignore during GPG signature verification.
See L(https://github.com/gpg/gnupg/blob/master/doc/DETAILS#general-status-codes) for status code descriptions.
- If fewer signatures successfully verify the collection than `GALAXY_REQUIRED_VALID_SIGNATURE_COUNT`,
signature verification will fail even if all error codes are ignored.
choices:
- EXPSIG
- EXPKEYSIG
- REVKEYSIG
- BADSIG
- ERRSIG
- NO_PUBKEY
- MISSING_PASSPHRASE
- BAD_PASSPHRASE
- NODATA
- UNEXPECTED
- ERROR
- FAILURE
- BADARMOR
- KEYEXPIRED
- KEYREVOKED
- NO_SECKEY
GALAXY_REQUIRED_VALID_SIGNATURE_COUNT:
type: str
default: 1
env:
- name: ANSIBLE_GALAXY_REQUIRED_VALID_SIGNATURE_COUNT
ini:
- section: galaxy
key: required_valid_signature_count
description:
- The number of signatures that must be successful during GPG signature verification while installing or verifying collections.
- This should be a positive integer or all to indicate all signatures must successfully validate the collection.
- Prepend + to the value to fail if no valid signatures are found for the collection.
GALAXY_COLLECTION_IMPORT_POLL_INTERVAL:
description:
- The initial interval in seconds for polling the import status of a collection.
- This interval increases exponentially based on the :ref:`galaxy_collection_import_poll_factor`, with a maximum delay of 30 seconds.
type: float
default: 2.0
env:
- name: ANSIBLE_GALAXY_COLLECTION_IMPORT_POLL_INTERVAL
version_added: '2.18'
GALAXY_COLLECTION_IMPORT_POLL_FACTOR:
description:
- The multiplier used to increase the :ref:`galaxy_collection_import_poll_interval` when checking the collection import status.
type: float
default: 1.5
env:
- name: ANSIBLE_GALAXY_COLLECTION_IMPORT_POLL_FACTOR
version_added: "2.18"
HOST_KEY_CHECKING:
# NOTE: constant not in use by ssh/paramiko plugins anymore, but they do support the same configuration sources
# TODO: check non ssh connection plugins for use/migration
name: Toggle host/key check
default: True
description:
- Set this to "False" if you want to avoid host key checking by the underlying connection plugin Ansible uses to connect to the host.
- Please read the documentation of the specific connection plugin used for details.
env: [{name: ANSIBLE_HOST_KEY_CHECKING}]
ini:
- {key: host_key_checking, section: defaults}
type: boolean
HOST_PATTERN_MISMATCH:
name: Control host pattern mismatch behaviour
default: 'warning'
description: This setting changes the behaviour of mismatched host patterns, it allows you to force a fatal error, a warning or just ignore it.
env: [{name: ANSIBLE_HOST_PATTERN_MISMATCH}]
ini:
- {key: host_pattern_mismatch, section: inventory}
choices:
<<: *basic_error
version_added: "2.8"
INTERPRETER_PYTHON:
name: Python interpreter path (or automatic discovery behavior) used for module execution
default: auto
env: [{name: ANSIBLE_PYTHON_INTERPRETER}]
ini:
- {key: interpreter_python, section: defaults}
vars:
- {name: ansible_python_interpreter}
version_added: "2.8"
description:
- Path to the Python interpreter to be used for module execution on remote targets, or an automatic discovery mode.
Supported discovery modes are ``auto`` (the default), ``auto_silent``, ``auto_legacy``, and ``auto_legacy_silent``.
All discovery modes match against an ordered list of well-known Python interpreter locations.
The fallback behavior will issue a warning that the interpreter should be set explicitly (since interpreters
installed later may change which one is used). This warning behavior can be disabled by setting ``auto_silent``.
The ``auto_legacy`` modes are deprecated and behave the same as their respective ``auto`` modes.
They exist for backward-compatibility with older Ansible releases that always defaulted to ``/usr/bin/python3``,
which will use that interpreter if present.
INTERPRETER_PYTHON_FALLBACK:
name: Ordered list of Python interpreters to check for in discovery
default:
- python3.13
- python3.12
- python3.11
- python3.10
- python3.9
- python3.8
- /usr/bin/python3
- python3
vars:
- name: ansible_interpreter_python_fallback
type: list
version_added: "2.8"
TRANSFORM_INVALID_GROUP_CHARS:
name: Transform invalid characters in group names
default: 'never'
description:
- Make ansible transform invalid characters in group names supplied by inventory sources.
env: [{name: ANSIBLE_TRANSFORM_INVALID_GROUP_CHARS}]
ini:
- {key: force_valid_group_names, section: defaults}
type: string
choices:
always: it will replace any invalid characters with '_' (underscore) and warn the user
never: it will allow for the group name but warn about the issue
ignore: it does the same as 'never', without issuing a warning
silently: it does the same as 'always', without issuing a warning
version_added: '2.8'
INVALID_TASK_ATTRIBUTE_FAILED:
name: Controls whether invalid attributes for a task result in errors instead of warnings
default: True
description: If 'false', invalid attributes for a task will result in warnings instead of errors.
type: boolean
env:
- name: ANSIBLE_INVALID_TASK_ATTRIBUTE_FAILED
ini:
- key: invalid_task_attribute_failed
section: defaults
version_added: "2.7"
INVENTORY_ANY_UNPARSED_IS_FAILED:
name: Controls whether any unparsable inventory source is a fatal error
default: False
description: >
If 'true', it is a fatal error when any given inventory source
cannot be successfully parsed by any available inventory plugin;
otherwise, this situation only attracts a warning.
type: boolean
env: [{name: ANSIBLE_INVENTORY_ANY_UNPARSED_IS_FAILED}]
ini:
- {key: any_unparsed_is_failed, section: inventory}
version_added: "2.7"
INVENTORY_ENABLED:
name: Active Inventory plugins
default: ['host_list', 'script', 'auto', 'yaml', 'ini', 'toml']
description: List of enabled inventory plugins, it also determines the order in which they are used.
env: [{name: ANSIBLE_INVENTORY_ENABLED}]
ini:
- {key: enable_plugins, section: inventory}
type: list
INVENTORY_EXPORT:
name: Set ansible-inventory into export mode
default: False
description: Controls if ansible-inventory will accurately reflect Ansible's view into inventory or its optimized for exporting.
env: [{name: ANSIBLE_INVENTORY_EXPORT}]
ini:
- {key: export, section: inventory}
type: bool
INVENTORY_IGNORE_EXTS:
name: Inventory ignore extensions
default: "{{ REJECT_EXTS + ['.orig', '.cfg', '.retry'] }}"
description: List of extensions to ignore when using a directory as an inventory source.
env: [{name: ANSIBLE_INVENTORY_IGNORE}]
ini:
- {key: inventory_ignore_extensions, section: defaults}
- {key: ignore_extensions, section: inventory}
type: list
INVENTORY_IGNORE_PATTERNS:
name: Inventory ignore patterns
default: []
description: List of patterns to ignore when using a directory as an inventory source.
env: [{name: ANSIBLE_INVENTORY_IGNORE_REGEX}]
ini:
- {key: inventory_ignore_patterns, section: defaults}
- {key: ignore_patterns, section: inventory}
type: list
INVENTORY_UNPARSED_IS_FAILED:
name: Unparsed Inventory failure
default: False
description: >
If 'true' it is a fatal error if every single potential inventory
source fails to parse, otherwise, this situation will only attract a
warning.
env: [{name: ANSIBLE_INVENTORY_UNPARSED_FAILED}]
ini:
- {key: unparsed_is_failed, section: inventory}
type: bool
MAX_FILE_SIZE_FOR_DIFF:
name: Diff maximum file size
default: 104448
description: Maximum size of files to be considered for diff display.
env: [{name: ANSIBLE_MAX_DIFF_SIZE}]
ini:
- {key: max_diff_size, section: defaults}
type: int
NETWORK_GROUP_MODULES:
name: Network module families
default: [eos, nxos, ios, iosxr, junos, enos, ce, vyos, sros, dellos9, dellos10, dellos6, asa, aruba, aireos, bigip, ironware, onyx, netconf, exos, voss, slxos]
description: 'TODO: write it'
env:
- name: ANSIBLE_NETWORK_GROUP_MODULES
ini:
- {key: network_group_modules, section: defaults}
type: list
yaml: {key: defaults.network_group_modules}
INJECT_FACTS_AS_VARS:
default: True
description:
- Facts are available inside the `ansible_facts` variable, this setting also pushes them as their own vars in the main namespace.
- Unlike inside the `ansible_facts` dictionary where the prefix `ansible_` is removed from fact names, these will have the exact names that are returned by the module.
env: [{name: ANSIBLE_INJECT_FACT_VARS}]
ini:
- {key: inject_facts_as_vars, section: defaults}
type: boolean
version_added: "2.5"
MODULE_IGNORE_EXTS:
name: Module ignore extensions
default: "{{ REJECT_EXTS + ['.yaml', '.yml', '.ini'] }}"
description:
- List of extensions to ignore when looking for modules to load.
- This is for rejecting script and binary module fallback extensions.
env: [{name: ANSIBLE_MODULE_IGNORE_EXTS}]
ini:
- {key: module_ignore_exts, section: defaults}
type: list
MODULE_STRICT_UTF8_RESPONSE:
name: Module strict UTF-8 response
description:
- Enables whether module responses are evaluated for containing non-UTF-8 data.
- Disabling this may result in unexpected behavior.
- Only ansible-core should evaluate this configuration.
env: [{name: ANSIBLE_MODULE_STRICT_UTF8_RESPONSE}]
ini:
- {key: module_strict_utf8_response, section: defaults}
type: bool
default: True
OLD_PLUGIN_CACHE_CLEARING:
description: Previously Ansible would only clear some of the plugin loading caches when loading new roles, this led to some behaviors in which a plugin loaded in previous plays would be unexpectedly 'sticky'. This setting allows the user to return to that behavior.
env: [{name: ANSIBLE_OLD_PLUGIN_CACHE_CLEAR}]
ini:
- {key: old_plugin_cache_clear, section: defaults}
type: boolean
default: False
version_added: "2.8"
PAGER:
name: pager application to use
default: less
description:
- for the cases in which Ansible needs to return output in a pageable fashion, this chooses the application to use.
ini:
- section: defaults
key: pager
version_added: '2.15'
env:
- name: ANSIBLE_PAGER
version_added: '2.15'
- name: PAGER
PARAMIKO_HOST_KEY_AUTO_ADD:
default: False
description: 'TODO: write it'
env: [{name: ANSIBLE_PARAMIKO_HOST_KEY_AUTO_ADD}]
ini:
- {key: host_key_auto_add, section: paramiko_connection}
type: boolean
deprecated:
why: This option was moved to the plugin itself
version: "2.20"
alternatives: Use the option from the plugin itself.
PARAMIKO_LOOK_FOR_KEYS:
name: look for keys
default: True
description: 'TODO: write it'
env: [{name: ANSIBLE_PARAMIKO_LOOK_FOR_KEYS}]
ini:
- {key: look_for_keys, section: paramiko_connection}
type: boolean
deprecated:
why: This option was moved to the plugin itself
version: "2.20"
alternatives: Use the option from the plugin itself.
PERSISTENT_CONTROL_PATH_DIR:
name: Persistence socket path
default: '{{ ANSIBLE_HOME ~ "/pc" }}'
description: Path to the socket to be used by the connection persistence system.
env: [{name: ANSIBLE_PERSISTENT_CONTROL_PATH_DIR}]
ini:
- {key: control_path_dir, section: persistent_connection}
type: path
PERSISTENT_CONNECT_TIMEOUT:
name: Persistence timeout
default: 30
description: This controls how long the persistent connection will remain idle before it is destroyed.
env: [{name: ANSIBLE_PERSISTENT_CONNECT_TIMEOUT}]
ini:
- {key: connect_timeout, section: persistent_connection}
type: integer
PERSISTENT_CONNECT_RETRY_TIMEOUT:
name: Persistence connection retry timeout
default: 15
description: This controls the retry timeout for persistent connection to connect to the local domain socket.
env: [{name: ANSIBLE_PERSISTENT_CONNECT_RETRY_TIMEOUT}]
ini:
- {key: connect_retry_timeout, section: persistent_connection}
type: integer
PERSISTENT_COMMAND_TIMEOUT:
name: Persistence command timeout
default: 30
description: This controls the amount of time to wait for a response from a remote device before timing out a persistent connection.
env: [{name: ANSIBLE_PERSISTENT_COMMAND_TIMEOUT}]
ini:
- {key: command_timeout, section: persistent_connection}
type: int
PLAYBOOK_DIR:
name: playbook dir override for non-playbook CLIs (ala --playbook-dir)
version_added: "2.9"
description:
- A number of non-playbook CLIs have a ``--playbook-dir`` argument; this sets the default value for it.
env: [{name: ANSIBLE_PLAYBOOK_DIR}]
ini: [{key: playbook_dir, section: defaults}]
type: path
PLAYBOOK_VARS_ROOT:
name: playbook vars files root
default: top
version_added: "2.4.1"
description:
- This sets which playbook dirs will be used as a root to process vars plugins, which includes finding host_vars/group_vars.
env: [{name: ANSIBLE_PLAYBOOK_VARS_ROOT}]
ini:
- {key: playbook_vars_root, section: defaults}
choices:
top: follows the traditional behavior of using the top playbook in the chain to find the root directory.
bottom: follows the 2.4.0 behavior of using the current playbook to find the root directory.
all: examines from the first parent to the current playbook.
PLUGIN_FILTERS_CFG:
name: Config file for limiting valid plugins
default: null
version_added: "2.5.0"
description:
- "A path to configuration for filtering which plugins installed on the system are allowed to be used."
- "See :ref:`plugin_filtering_config` for details of the filter file's format."
- " The default is /etc/ansible/plugin_filters.yml"
ini:
- key: plugin_filters_cfg
section: defaults
type: path
PYTHON_MODULE_RLIMIT_NOFILE:
name: Adjust maximum file descriptor soft limit during Python module execution
description:
- Attempts to set RLIMIT_NOFILE soft limit to the specified value when executing Python modules (can speed up subprocess usage on
Python 2.x. See https://bugs.python.org/issue11284). The value will be limited by the existing hard limit. Default
value of 0 does not attempt to adjust existing system-defined limits.
default: 0
env:
- {name: ANSIBLE_PYTHON_MODULE_RLIMIT_NOFILE}
ini:
- {key: python_module_rlimit_nofile, section: defaults}
vars:
- {name: ansible_python_module_rlimit_nofile}
version_added: '2.8'
RETRY_FILES_ENABLED:
name: Retry files
default: False
description: This controls whether a failed Ansible playbook should create a .retry file.
env: [{name: ANSIBLE_RETRY_FILES_ENABLED}]
ini:
- {key: retry_files_enabled, section: defaults}
type: bool
RETRY_FILES_SAVE_PATH:
name: Retry files path
default: ~
description:
- This sets the path in which Ansible will save .retry files when a playbook fails and retry files are enabled.
- This file will be overwritten after each run with the list of failed hosts from all plays.
env: [{name: ANSIBLE_RETRY_FILES_SAVE_PATH}]
ini:
- {key: retry_files_save_path, section: defaults}
type: path
RUN_VARS_PLUGINS:
name: When should vars plugins run relative to inventory
default: demand
description:
- This setting can be used to optimize vars_plugin usage depending on the user's inventory size and play selection.
env: [{name: ANSIBLE_RUN_VARS_PLUGINS}]
ini:
- {key: run_vars_plugins, section: defaults}
type: str
choices:
demand: will run vars_plugins relative to inventory sources anytime vars are 'demanded' by tasks.
start: will run vars_plugins relative to inventory sources after importing that inventory source.
version_added: "2.10"
SHOW_CUSTOM_STATS:
name: Display custom stats
default: False
description: 'This adds the custom stats set via the set_stats plugin to the default output.'
env: [{name: ANSIBLE_SHOW_CUSTOM_STATS}]
ini:
- {key: show_custom_stats, section: defaults}
type: bool
SSH_AGENT:
name: Manage an SSH Agent
description: Manage an SSH Agent via Ansible. A configuration of ``none`` will not interact with an agent,
``auto`` will start and destroy an agent via ``ssh-agent`` binary during the run, and a path
to an SSH_AUTH_SOCK will allow interaction with a pre-existing agent.
default: none
type: string
env: [{name: ANSIBLE_SSH_AGENT}]
ini: [{key: ssh_agent, section: connection}]
version_added: '2.19'
SSH_AGENT_KEY_LIFETIME:
name: Set a maximum lifetime when adding identities to an agent
description: For keys inserted into an agent defined by ``SSH_AGENT``, define a lifetime, in seconds, that the key may remain
in the agent.
type: int
env: [{name: ANSIBLE_SSH_AGENT_KEY_LIFETIME}]
ini: [{key: ssh_agent_key_lifetime, section: connection}]
version_added: '2.19'
STRING_TYPE_FILTERS:
name: Filters to preserve strings
default: [string, to_json, to_nice_json, to_yaml, to_nice_yaml, ppretty, json]
description:
- "This list of filters avoids 'type conversion' when templating variables."
- Useful when you want to avoid conversion into lists or dictionaries for JSON strings, for example.
env: [{name: ANSIBLE_STRING_TYPE_FILTERS}]
ini:
- {key: dont_type_filters, section: jinja2}
type: list
deprecated:
why: This option has no effect.
version: "2.23"
alternatives: None; native types returned from filters are always preserved.
SYSTEM_WARNINGS:
name: System warnings
default: True
description:
- Allows disabling of warnings related to potential issues on the system running Ansible itself (not on the managed hosts).
- These may include warnings about third-party packages or other conditions that should be resolved if possible.
env: [{name: ANSIBLE_SYSTEM_WARNINGS}]
ini:
- {key: system_warnings, section: defaults}
type: boolean
TAGS_RUN:
name: Run Tags
default: []
type: list
description: default list of tags to run in your plays, Skip Tags has precedence.
env: [{name: ANSIBLE_RUN_TAGS}]
ini:
- {key: run, section: tags}
version_added: "2.5"
TAGS_SKIP:
name: Skip Tags
default: []
type: list
description: default list of tags to skip in your plays, has precedence over Run Tags
env: [{name: ANSIBLE_SKIP_TAGS}]
ini:
- {key: skip, section: tags}
version_added: "2.5"
TARGET_LOG_INFO:
name: Target log info
description: A string to insert into target logging for tracking purposes
env: [{name: ANSIBLE_TARGET_LOG_INFO}]
ini:
- {key: target_log_info, section: defaults}
vars:
- name: ansible_target_log_info
version_added: "2.17"
TASK_TIMEOUT:
name: Task Timeout
default: 0
description:
- Set the maximum time (in seconds) for a task action to execute in.
- Timeout runs independently from templating or looping.
It applies per each attempt of executing the task's action and remains unchanged by the total time spent on a task.
- When the action execution exceeds the timeout, Ansible interrupts the process.
This is registered as a failure due to outside circumstances, not a task failure, to receive appropriate response and recovery process.
- If set to 0 (the default) there is no timeout.
env: [{name: ANSIBLE_TASK_TIMEOUT}]
ini:
- {key: task_timeout, section: defaults}
type: integer
version_added: '2.10'
_TEMPLAR_UNKNOWN_TYPE_CONVERSION:
name: Templar unknown type conversion behavior
default: warning
description:
- Action to take when an unknown type is converted for variable storage during template finalization.
- This setting has no effect on the inability to store unsupported variable types as the result of templating.
- Experimental diagnostic feature, subject to change.
type: choices
choices: *basic_error
env: [{name: _ANSIBLE_TEMPLAR_UNKNOWN_TYPE_CONVERSION}]
version_added: '2.19'
_TEMPLAR_UNKNOWN_TYPE_ENCOUNTERED:
name: Templar unknown type encountered behavior
default: ignore
description:
- Action to take when an unknown type is encountered inside a template pipeline.
- Experimental diagnostic feature, subject to change.
type: choices
choices: *basic_error
env: [{name: _ANSIBLE_TEMPLAR_UNKNOWN_TYPE_ENCOUNTERED}]
version_added: '2.19'
_TEMPLAR_UNTRUSTED_TEMPLATE_BEHAVIOR:
name: Templar untrusted template behavior
default: ignore
description:
- Action to take when processing of an untrusted template is skipped.
- For `ignore` or `warn`, the input template string is returned as-is.
- This setting has no effect on expressions.
- Experimental diagnostic feature, subject to change.
type: choices
choices: *basic_error
env: [{name: _ANSIBLE_TEMPLAR_UNTRUSTED_TEMPLATE_BEHAVIOR}]
version_added: '2.19'
WORKER_SHUTDOWN_POLL_COUNT:
name: Worker Shutdown Poll Count
default: 0
description:
- The maximum number of times to check Task Queue Manager worker processes to verify they have exited cleanly.
- After this limit is reached any worker processes still running will be terminated.
- This is for internal use only.
env: [{name: ANSIBLE_WORKER_SHUTDOWN_POLL_COUNT}]
type: integer
version_added: '2.10'
WORKER_SHUTDOWN_POLL_DELAY:
name: Worker Shutdown Poll Delay
default: 0.1
description:
- The number of seconds to sleep between polling loops when checking Task Queue Manager worker processes to verify they have exited cleanly.
- This is for internal use only.
env: [{name: ANSIBLE_WORKER_SHUTDOWN_POLL_DELAY}]
type: float
version_added: '2.10'
USE_PERSISTENT_CONNECTIONS:
name: Persistence
default: False
description: Toggles the use of persistence for connections.
env: [{name: ANSIBLE_USE_PERSISTENT_CONNECTIONS}]
ini:
- {key: use_persistent_connections, section: defaults}
type: boolean
VARIABLE_PLUGINS_ENABLED:
name: Vars plugin enabled list
default: ['host_group_vars']
description: Accept list for variable plugins that require it.
env: [{name: ANSIBLE_VARS_ENABLED}]
ini:
- {key: vars_plugins_enabled, section: defaults}
type: list
version_added: "2.10"
VARIABLE_PRECEDENCE:
name: Group variable precedence
default: ['all_inventory', 'groups_inventory', 'all_plugins_inventory', 'all_plugins_play', 'groups_plugins_inventory', 'groups_plugins_play']
description: Allows to change the group variable precedence merge order.
env: [{name: ANSIBLE_PRECEDENCE}]
ini:
- {key: precedence, section: defaults}
type: list
version_added: "2.4"
WIN_ASYNC_STARTUP_TIMEOUT:
name: Windows Async Startup Timeout
default: 5
description:
- For asynchronous tasks in Ansible (covered in Asynchronous Actions and Polling),
this is how long, in seconds, to wait for the task spawned by Ansible to connect back to the named pipe used
on Windows systems. The default is 5 seconds. This can be too low on slower systems, or systems under heavy load.
- This is not the total time an async command can run for, but is a separate timeout to wait for an async command to
start. The task will only start to be timed against its async_timeout once it has connected to the pipe, so the
overall maximum duration the task can take will be extended by the amount specified here.
env: [{name: ANSIBLE_WIN_ASYNC_STARTUP_TIMEOUT}]
ini:
- {key: win_async_startup_timeout, section: defaults}
type: integer
vars:
- {name: ansible_win_async_startup_timeout}
version_added: '2.10'
WRAP_STDERR:
description: Control line-wrapping behavior on console warnings and errors from default output callbacks (eases pattern-based output testing)
env: [{name: ANSIBLE_WRAP_STDERR}]
default: false
type: bool
version_added: "2.19"
YAML_FILENAME_EXTENSIONS:
name: Valid YAML extensions
default: [".yml", ".yaml", ".json"]
description:
- "Check all of these extensions when looking for 'variable' files which should be YAML or JSON or vaulted versions of these."
- 'This affects vars_files, include_vars, inventory and vars plugins among others.'
env:
- name: ANSIBLE_YAML_FILENAME_EXT
ini:
- section: defaults
key: yaml_valid_extensions
type: list
NETCONF_SSH_CONFIG:
description: This variable is used to enable bastion/jump host with netconf connection. If set to True the bastion/jump
host ssh settings should be present in ~/.ssh/config file, alternatively it can be set
to custom ssh configuration file path to read the bastion/jump host settings.
env: [{name: ANSIBLE_NETCONF_SSH_CONFIG}]
ini:
- {key: ssh_config, section: netconf_connection}
yaml: {key: netconf_connection.ssh_config}
default: null
VALIDATE_ACTION_GROUP_METADATA:
version_added: '2.12'
description:
- A toggle to disable validating a collection's 'metadata' entry for a module_defaults action group.
Metadata containing unexpected fields or value types will produce a warning when this is True.
default: True
env: [{name: ANSIBLE_VALIDATE_ACTION_GROUP_METADATA}]
ini:
- section: defaults
key: validate_action_group_metadata
type: bool
VERBOSE_TO_STDERR:
version_added: '2.8'
description:
- Force 'verbose' option to use stderr instead of stdout
default: False
env:
- name: ANSIBLE_VERBOSE_TO_STDERR
ini:
- section: defaults
key: verbose_to_stderr
type: bool
_Z_TEST_ENTRY:
name: testentry
description: for tests
env:
- name: ANSIBLE_TEST_ENTRY
- name: ANSIBLE_TEST_ENTRY_D
deprecated:
why: for testing
version: '3.30'
alternatives: nothing
ini:
- section: testing
key: valid
- section: testing
key: deprecated
deprecated:
why: for testing
version: '3.30'
alternatives: nothing
_Z_TEST_ENTRY_2:
version_added: '2.18'
name: testentry
description: for tests
deprecated:
why: for testing
version: '3.30'
alternatives: nothing
env:
- name: ANSIBLE_TEST_ENTRY2
ini:
- section: testing
key: valid2
ansible_core-2.19.0b4/lib/ansible/config/manager.py 0000644 0000000 0000000 00000074623 15010426755 020651 0 ustar 00root root # Copyright: (c) 2017, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import annotations
import atexit
import decimal
import configparser
import os
import os.path
import sys
import stat
import tempfile
import typing as t
from collections.abc import Mapping, Sequence
from jinja2.nativetypes import NativeEnvironment
from ansible._internal._datatag import _tags
from ansible.errors import AnsibleOptionsError, AnsibleError, AnsibleUndefinedConfigEntry, AnsibleRequiredOptionError
from ansible.module_utils._internal._datatag import AnsibleTagHelper
from ansible.module_utils.common.sentinel import Sentinel
from ansible.module_utils.common.text.converters import to_text, to_bytes, to_native
from ansible.module_utils.common.yaml import yaml_load
from ansible.module_utils.parsing.convert_bool import boolean
from ansible.parsing.quoting import unquote
from ansible.utils.path import cleanup_tmp_file, makedirs_safe, unfrackpath
INTERNAL_DEFS = {'lookup': ('_terms',)}
GALAXY_SERVER_DEF = [
('url', True, 'str'),
('username', False, 'str'),
('password', False, 'str'),
('token', False, 'str'),
('auth_url', False, 'str'),
('api_version', False, 'int'),
('validate_certs', False, 'bool'),
('client_id', False, 'str'),
('client_secret', False, 'str'),
('timeout', False, 'int'),
]
# config definition fields
GALAXY_SERVER_ADDITIONAL = {
'api_version': {'default': None, 'choices': [2, 3]},
'validate_certs': {'cli': [{'name': 'validate_certs'}]},
'timeout': {'cli': [{'name': 'timeout'}]},
'token': {'default': None},
}
@t.runtime_checkable
class _EncryptedStringProtocol(t.Protocol):
"""Protocol representing an `EncryptedString`, since it cannot be imported here."""
# DTFIX-FUTURE: collapse this with the one in collection loader, once we can
def _decrypt(self) -> str: ...
def _get_config_label(plugin_type: str, plugin_name: str, config: str) -> str:
"""Return a label for the given config."""
entry = f'{config!r}'
if plugin_type:
entry += ' for'
if plugin_name:
entry += f' {plugin_name!r}'
entry += f' {plugin_type} plugin'
return entry
def ensure_type(value: object, value_type: str | None, origin: str | None = None, origin_ftype: str | None = None) -> t.Any:
"""
Converts `value` to the requested `value_type`; raises `ValueError` for failed conversions.
Values for `value_type` are:
* boolean/bool: Return a `bool` by applying non-strict `bool` filter rules:
'y', 'yes', 'on', '1', 'true', 't', 1, 1.0, True return True, any other value is False.
* integer/int: Return an `int`. Accepts any `str` parseable by `int` or numeric value with a zero mantissa (including `bool`).
* float: Return a `float`. Accepts any `str` parseable by `float` or numeric value (including `bool`).
* list: Return a `list`. Accepts `list` or `Sequence`. Also accepts, `str`, splitting on ',' while stripping whitespace and unquoting items.
* none: Return `None`. Accepts only the string "None".
* path: Return a resolved path. Accepts `str`.
* temppath/tmppath/tmp: Return a unique temporary directory inside the resolved path specified by the value.
* pathspec: Return a `list` of resolved paths. Accepts a `list` or `Sequence`. Also accepts `str`, splitting on ':'.
* pathlist: Return a `list` of resolved paths. Accepts a `list` or `Sequence`. Also accepts `str`, splitting on `,` while stripping whitespace from paths.
* dictionary/dict: Return a `dict`. Accepts `dict` or `Mapping`.
* string/str: Return a `str`. Accepts `bool`, `int`, `float`, `complex` or `str`.
Path resolution ensures paths are `str` with expansion of '{{CWD}}', environment variables and '~'.
Non-absolute paths are expanded relative to the basedir from `origin`, if specified.
No conversion is performed if `value_type` is unknown or `value` is `None`.
When `origin_ftype` is "ini", a `str` result will be unquoted.
"""
if value is None:
return None
original_value = value
copy_tags = value_type not in ('temppath', 'tmppath', 'tmp')
value = _ensure_type(value, value_type, origin)
if copy_tags and value is not original_value:
if isinstance(value, list):
value = [AnsibleTagHelper.tag_copy(original_value, item) for item in value]
value = AnsibleTagHelper.tag_copy(original_value, value)
if isinstance(value, str) and origin_ftype and origin_ftype == 'ini':
value = unquote(value)
return value
def _ensure_type(value: object, value_type: str | None, origin: str | None = None) -> t.Any:
"""Internal implementation for `ensure_type`, call that function instead."""
original_value = value
basedir = origin if origin and os.path.isabs(origin) and os.path.exists(to_bytes(origin)) else None
if value_type:
value_type = value_type.lower()
match value_type:
case 'boolean' | 'bool':
return boolean(value, strict=False)
case 'integer' | 'int':
if isinstance(value, int): # handle both int and bool (which is an int)
return int(value)
if isinstance(value, (float, str)):
try:
# use Decimal for all other source type conversions; non-zero mantissa is a failure
if (decimal_value := decimal.Decimal(value)) == (int_part := int(decimal_value)):
return int_part
except (decimal.DecimalException, ValueError):
pass
case 'float':
if isinstance(value, float):
return value
if isinstance(value, (int, str)):
try:
return float(value)
except ValueError:
pass
case 'list':
if isinstance(value, list):
return value
if isinstance(value, str):
return [unquote(x.strip()) for x in value.split(',')]
if isinstance(value, Sequence) and not isinstance(value, bytes):
return list(value)
case 'none':
if value == "None":
return None
case 'path':
if isinstance(value, str):
return resolve_path(value, basedir=basedir)
case 'temppath' | 'tmppath' | 'tmp':
if isinstance(value, str):
value = resolve_path(value, basedir=basedir)
if not os.path.exists(value):
makedirs_safe(value, 0o700)
prefix = 'ansible-local-%s' % os.getpid()
value = tempfile.mkdtemp(prefix=prefix, dir=value)
atexit.register(cleanup_tmp_file, value, warn=True)
return value
case 'pathspec':
if isinstance(value, str):
value = value.split(os.pathsep)
if isinstance(value, Sequence) and not isinstance(value, bytes) and all(isinstance(x, str) for x in value):
return [resolve_path(x, basedir=basedir) for x in value]
case 'pathlist':
if isinstance(value, str):
value = [x.strip() for x in value.split(',')]
if isinstance(value, Sequence) and not isinstance(value, bytes) and all(isinstance(x, str) for x in value):
return [resolve_path(x, basedir=basedir) for x in value]
case 'dictionary' | 'dict':
if isinstance(value, dict):
return value
if isinstance(value, Mapping):
return dict(value)
case 'string' | 'str':
if isinstance(value, str):
return value
if isinstance(value, (bool, int, float, complex)):
return str(value)
if isinstance(value, _EncryptedStringProtocol):
return value._decrypt()
case _:
# FIXME: define and document a pass-through value_type (None, 'raw', 'object', '', ...) and then deprecate acceptance of unknown types
return value # return non-str values of unknown value_type as-is
raise ValueError(f'Invalid value provided for {value_type!r}: {original_value!r}')
# FIXME: see if this can live in utils/path
def resolve_path(path: str, basedir: str | None = None) -> str:
""" resolve relative or 'variable' paths """
if '{{CWD}}' in path: # allow users to force CWD using 'magic' {{CWD}}
path = path.replace('{{CWD}}', os.getcwd())
return unfrackpath(path, follow=False, basedir=basedir)
# FIXME: generic file type?
def get_config_type(cfile):
ftype = None
if cfile is not None:
ext = os.path.splitext(cfile)[-1]
if ext in ('.ini', '.cfg'):
ftype = 'ini'
elif ext in ('.yaml', '.yml'):
ftype = 'yaml'
else:
raise AnsibleOptionsError("Unsupported configuration file extension for %s: %s" % (cfile, to_native(ext)))
return ftype
# FIXME: can move to module_utils for use for ini plugins also?
def get_ini_config_value(p, entry):
""" returns the value of last ini entry found """
value = None
if p is not None:
try:
value = p.get(entry.get('section', 'defaults'), entry.get('key', ''), raw=True)
except Exception: # FIXME: actually report issues here
pass
return value
def find_ini_config_file(warnings=None):
""" Load INI Config File order(first found is used): ENV, CWD, HOME, /etc/ansible """
# FIXME: eventually deprecate ini configs
if warnings is None:
# Note: In this case, warnings does nothing
warnings = set()
potential_paths = []
# A value that can never be a valid path so that we can tell if ANSIBLE_CONFIG was set later
# We can't use None because we could set path to None.
# Environment setting
path_from_env = os.getenv("ANSIBLE_CONFIG", Sentinel)
if path_from_env is not Sentinel:
path_from_env = unfrackpath(path_from_env, follow=False)
if os.path.isdir(to_bytes(path_from_env)):
path_from_env = os.path.join(path_from_env, "ansible.cfg")
potential_paths.append(path_from_env)
# Current working directory
warn_cmd_public = False
try:
cwd = os.getcwd()
perms = os.stat(cwd)
cwd_cfg = os.path.join(cwd, "ansible.cfg")
if perms.st_mode & stat.S_IWOTH:
# Working directory is world writable so we'll skip it.
# Still have to look for a file here, though, so that we know if we have to warn
if os.path.exists(cwd_cfg):
warn_cmd_public = True
else:
potential_paths.append(to_text(cwd_cfg, errors='surrogate_or_strict'))
except OSError:
# If we can't access cwd, we'll simply skip it as a possible config source
pass
# Per user location
potential_paths.append(unfrackpath("~/.ansible.cfg", follow=False))
# System location
potential_paths.append("/etc/ansible/ansible.cfg")
for path in potential_paths:
b_path = to_bytes(path)
if os.path.exists(b_path) and os.access(b_path, os.R_OK):
break
else:
path = None
# Emit a warning if all the following are true:
# * We did not use a config from ANSIBLE_CONFIG
# * There's an ansible.cfg in the current working directory that we skipped
if path_from_env != path and warn_cmd_public:
warnings.add(u"Ansible is being run in a world writable directory (%s),"
u" ignoring it as an ansible.cfg source."
u" For more information see"
u" https://docs.ansible.com/ansible/devel/reference_appendices/config.html#cfg-in-world-writable-dir"
% to_text(cwd))
return path
def _add_base_defs_deprecations(base_defs):
"""Add deprecation source 'ansible.builtin' to deprecations in base.yml"""
def process(entry):
if 'deprecated' in entry:
entry['deprecated']['collection_name'] = 'ansible.builtin'
for dummy, data in base_defs.items():
process(data)
for section in ('ini', 'env', 'vars'):
if section in data:
for entry in data[section]:
process(entry)
class ConfigManager:
DEPRECATED = [] # type: list[tuple[str, dict[str, str]]]
WARNINGS = set() # type: set[str]
_errors: list[tuple[str, Exception]]
def __init__(self, conf_file=None, defs_file=None):
self._base_defs = {}
self._plugins = {}
self._parsers = {}
self._config_file = conf_file
self._base_defs = self._read_config_yaml_file(defs_file or ('%s/base.yml' % os.path.dirname(__file__)))
_add_base_defs_deprecations(self._base_defs)
if self._config_file is None:
# set config using ini
self._config_file = find_ini_config_file(self.WARNINGS)
# consume configuration
if self._config_file:
# initialize parser and read config
self._parse_config_file()
self._errors = []
"""Deferred errors that will be turned into warnings."""
# ensure we always have config def entry
self._base_defs['CONFIG_FILE'] = {'default': None, 'type': 'path'}
def load_galaxy_server_defs(self, server_list):
def server_config_def(section, key, required, option_type):
config_def = {
'description': 'The %s of the %s Galaxy server' % (key, section),
'ini': [
{
'section': 'galaxy_server.%s' % section,
'key': key,
}
],
'env': [
{'name': 'ANSIBLE_GALAXY_SERVER_%s_%s' % (section.upper(), key.upper())},
],
'required': required,
'type': option_type,
}
if key in GALAXY_SERVER_ADDITIONAL:
config_def.update(GALAXY_SERVER_ADDITIONAL[key])
# ensure we always have a default timeout
if key == 'timeout' and 'default' not in config_def:
config_def['default'] = self.get_config_value('GALAXY_SERVER_TIMEOUT')
return config_def
if server_list:
for server_key in server_list:
if not server_key:
# To filter out empty strings or non truthy values as an empty server list env var is equal to [''].
continue
# Config definitions are looked up dynamically based on the C.GALAXY_SERVER_LIST entry. We look up the
# section [galaxy_server.] for the values url, username, password, and token.
defs = dict((k, server_config_def(server_key, k, req, value_type)) for k, req, value_type in GALAXY_SERVER_DEF)
self.initialize_plugin_configuration_definitions('galaxy_server', server_key, defs)
def template_default(self, value, variables, key_name: str = ''):
if isinstance(value, str) and (value.startswith('{{') and value.endswith('}}')) and variables is not None:
# template default values if possible
# NOTE: cannot use is_template due to circular dep
try:
# FIXME: This really should be using an immutable sandboxed native environment, not just native environment
template = NativeEnvironment().from_string(value)
value = template.render(variables)
except Exception as ex:
self._errors.append((f'Failed to template default for config {key_name}.', ex))
return value
def _read_config_yaml_file(self, yml_file):
# TODO: handle relative paths as relative to the directory containing the current playbook instead of CWD
# Currently this is only used with absolute paths to the `ansible/config` directory
yml_file = to_bytes(yml_file)
if os.path.exists(yml_file):
with open(yml_file, 'rb') as config_def:
return yaml_load(config_def) or {}
raise AnsibleError(
"Missing base YAML definition file (bad install?): %s" % to_native(yml_file))
def _parse_config_file(self, cfile=None):
""" return flat configuration settings from file(s) """
# TODO: take list of files with merge/nomerge
if cfile is None:
cfile = self._config_file
ftype = get_config_type(cfile)
if cfile is not None:
if ftype == 'ini':
self._parsers[cfile] = configparser.ConfigParser(inline_comment_prefixes=(';',))
with open(to_bytes(cfile), 'rb') as f:
try:
cfg_text = to_text(f.read(), errors='surrogate_or_strict')
except UnicodeError as e:
raise AnsibleOptionsError("Error reading config file(%s) because the config file was not utf8 encoded: %s" % (cfile, to_native(e)))
try:
self._parsers[cfile].read_string(cfg_text)
except configparser.Error as e:
raise AnsibleOptionsError("Error reading config file (%s): %s" % (cfile, to_native(e)))
# FIXME: this should eventually handle yaml config files
# elif ftype == 'yaml':
# with open(cfile, 'rb') as config_stream:
# self._parsers[cfile] = yaml_load(config_stream)
else:
raise AnsibleOptionsError("Unsupported configuration file type: %s" % to_native(ftype))
def _find_yaml_config_files(self):
""" Load YAML Config Files in order, check merge flags, keep origin of settings"""
pass
def get_plugin_options(self, plugin_type, name, keys=None, variables=None, direct=None):
options = {}
defs = self.get_configuration_definitions(plugin_type=plugin_type, name=name)
for option in defs:
options[option] = self.get_config_value(option, plugin_type=plugin_type, plugin_name=name, keys=keys, variables=variables, direct=direct)
return options
def get_plugin_vars(self, plugin_type, name):
pvars = []
for pdef in self.get_configuration_definitions(plugin_type=plugin_type, name=name).values():
if 'vars' in pdef and pdef['vars']:
for var_entry in pdef['vars']:
pvars.append(var_entry['name'])
return pvars
def get_plugin_options_from_var(self, plugin_type, name, variable):
options = []
for option_name, pdef in self.get_configuration_definitions(plugin_type=plugin_type, name=name).items():
if 'vars' in pdef and pdef['vars']:
for var_entry in pdef['vars']:
if variable == var_entry['name']:
options.append(option_name)
return options
def get_configuration_definition(self, name, plugin_type=None, plugin_name=None):
ret = {}
if plugin_type is None:
ret = self._base_defs.get(name, None)
elif plugin_name is None:
ret = self._plugins.get(plugin_type, {}).get(name, None)
else:
ret = self._plugins.get(plugin_type, {}).get(plugin_name, {}).get(name, None)
return ret
def has_configuration_definition(self, plugin_type, name):
has = False
if plugin_type in self._plugins:
has = (name in self._plugins[plugin_type])
return has
def get_configuration_definitions(self, plugin_type=None, name=None, ignore_private=False):
""" just list the possible settings, either base or for specific plugins or plugin """
ret = {}
if plugin_type is None:
ret = self._base_defs
elif name is None:
ret = self._plugins.get(plugin_type, {})
else:
ret = self._plugins.get(plugin_type, {}).get(name, {})
if ignore_private: # ignore 'test' config entries, they should not change runtime behaviors
for cdef in list(ret.keys()):
if cdef.startswith('_Z_'):
del ret[cdef]
return ret
def _loop_entries(self, container, entry_list):
""" repeat code for value entry assignment """
value = None
origin = None
for entry in entry_list:
name = entry.get('name')
try:
temp_value = container.get(name, None)
except UnicodeEncodeError:
self.WARNINGS.add(u'value for config entry {0} contains invalid characters, ignoring...'.format(to_text(name)))
continue
if temp_value is not None: # only set if entry is defined in container
value = temp_value
origin = name
# deal with deprecation of setting source, if used
if 'deprecated' in entry:
self.DEPRECATED.append((entry['name'], entry['deprecated']))
return value, origin
def get_config_value(self, config, cfile=None, plugin_type=None, plugin_name=None, keys=None, variables=None, direct=None):
""" wrapper """
try:
value, _drop = self.get_config_value_and_origin(config, cfile=cfile, plugin_type=plugin_type, plugin_name=plugin_name,
keys=keys, variables=variables, direct=direct)
except AnsibleError:
raise
except Exception as ex:
raise AnsibleError(f"Unhandled exception when retrieving {config!r}.") from ex
return value
def get_config_default(self, config: str, plugin_type: str | None = None, plugin_name: str | None = None) -> t.Any:
"""Return the default value for the specified configuration."""
return self.get_configuration_definitions(plugin_type, plugin_name)[config]['default']
def get_config_value_and_origin(self, config, cfile=None, plugin_type=None, plugin_name=None, keys=None, variables=None, direct=None):
""" Given a config key figure out the actual value and report on the origin of the settings """
if cfile is None:
# use default config
cfile = self._config_file
if config == 'CONFIG_FILE':
return cfile, ''
# Note: sources that are lists listed in low to high precedence (last one wins)
value = None
origin = None
origin_ftype = None
defs = self.get_configuration_definitions(plugin_type=plugin_type, name=plugin_name)
if config in defs:
aliases = defs[config].get('aliases', [])
# direct setting via plugin arguments, can set to None so we bypass rest of processing/defaults
if direct:
if config in direct:
value = direct[config]
origin = 'Direct'
else:
direct_aliases = [direct[alias] for alias in aliases if alias in direct]
if direct_aliases:
value = direct_aliases[0]
origin = 'Direct'
if value is None and variables and defs[config].get('vars'):
# Use 'variable overrides' if present, highest precedence, but only present when querying running play
value, origin = self._loop_entries(variables, defs[config]['vars'])
origin = 'var: %s' % origin
# use playbook keywords if you have em
if value is None and defs[config].get('keyword') and keys:
value, origin = self._loop_entries(keys, defs[config]['keyword'])
origin = 'keyword: %s' % origin
# automap to keywords
# TODO: deprecate these in favor of explicit keyword above
if value is None and keys:
if config in keys:
value = keys[config]
keyword = config
elif aliases:
for alias in aliases:
if alias in keys:
value = keys[alias]
keyword = alias
break
if value is not None:
origin = 'keyword: %s' % keyword
if value is None and 'cli' in defs[config]:
# avoid circular import .. until valid
from ansible import context
value, origin = self._loop_entries(context.CLIARGS, defs[config]['cli'])
origin = 'cli: %s' % origin
# env vars are next precedence
if value is None and defs[config].get('env'):
value, origin = self._loop_entries(os.environ, defs[config]['env'])
origin = 'env: %s' % origin
# try config file entries next, if we have one
if self._parsers.get(cfile, None) is None:
self._parse_config_file(cfile)
# attempt to read from config file
if value is None and cfile is not None:
ftype = get_config_type(cfile)
if ftype and defs[config].get(ftype):
try:
for entry in defs[config][ftype]:
# load from config
if ftype == 'ini':
temp_value = get_ini_config_value(self._parsers[cfile], entry)
elif ftype == 'yaml':
raise AnsibleError('YAML configuration type has not been implemented yet')
else:
raise AnsibleError('Invalid configuration file type: %s' % ftype)
if temp_value is not None:
# set value and origin
value = temp_value
origin = cfile
origin_ftype = ftype
if 'deprecated' in entry:
if ftype == 'ini':
self.DEPRECATED.append(('[%s]%s' % (entry['section'], entry['key']), entry['deprecated']))
else:
raise AnsibleError('Unimplemented file type: %s' % ftype)
except Exception as e:
sys.stderr.write("Error while loading config %s: %s" % (cfile, to_native(e)))
# set default if we got here w/o a value
if value is None:
if defs[config].get('required', False):
if not plugin_type or config not in INTERNAL_DEFS.get(plugin_type, {}):
raise AnsibleRequiredOptionError(f"Required config {_get_config_label(plugin_type, plugin_name, config)} not provided.")
else:
origin = 'default'
value = self.template_default(defs[config].get('default'), variables, key_name=_get_config_label(plugin_type, plugin_name, config))
try:
# ensure correct type, can raise exceptions on mismatched types
value = ensure_type(value, defs[config].get('type'), origin=origin, origin_ftype=origin_ftype)
except ValueError as ex:
if origin.startswith('env:') and value == '':
# this is empty env var for non string so we can set to default
origin = 'default'
value = ensure_type(defs[config].get('default'), defs[config].get('type'), origin=origin, origin_ftype=origin_ftype)
else:
raise AnsibleOptionsError(f'Config {_get_config_label(plugin_type, plugin_name, config)} from {origin!r} has an invalid value.') from ex
# deal with restricted values
if value is not None and 'choices' in defs[config] and defs[config]['choices'] is not None:
invalid_choices = True # assume the worst!
if defs[config].get('type') == 'list':
# for a list type, compare all values in type are allowed
invalid_choices = not all(choice in defs[config]['choices'] for choice in value)
else:
# these should be only the simple data types (string, int, bool, float, etc) .. ignore dicts for now
invalid_choices = value not in defs[config]['choices']
if invalid_choices:
if isinstance(defs[config]['choices'], Mapping):
valid = ', '.join([to_text(k) for k in defs[config]['choices'].keys()])
elif isinstance(defs[config]['choices'], str):
valid = defs[config]['choices']
elif isinstance(defs[config]['choices'], Sequence):
valid = ', '.join([to_text(c) for c in defs[config]['choices']])
else:
valid = defs[config]['choices']
raise AnsibleOptionsError(f'Invalid value {value!r} for config {_get_config_label(plugin_type, plugin_name, config)}.',
help_text=f'Valid values are: {valid}')
# deal with deprecation of the setting
if 'deprecated' in defs[config] and origin != 'default':
self.DEPRECATED.append((config, defs[config].get('deprecated')))
else:
raise AnsibleUndefinedConfigEntry(f'No config definition exists for {_get_config_label(plugin_type, plugin_name, config)}.')
if not _tags.Origin.is_tagged_on(value):
value = _tags.Origin(description=f'').tag(value)
return value, origin
def initialize_plugin_configuration_definitions(self, plugin_type, name, defs):
if plugin_type not in self._plugins:
self._plugins[plugin_type] = {}
self._plugins[plugin_type][name] = defs
@staticmethod
def get_deprecated_msg_from_config(dep_docs, include_removal=False, collection_name=None):
removal = ''
if include_removal:
if 'removed_at_date' in dep_docs:
removal = f"Will be removed in a release after {dep_docs['removed_at_date']}\n\t"
elif collection_name:
removal = f"Will be removed in: {collection_name} {dep_docs['removed_in']}\n\t"
else:
removal = f"Will be removed in: Ansible {dep_docs['removed_in']}\n\t"
# TODO: choose to deprecate either singular or plural
alt = dep_docs.get('alternatives', dep_docs.get('alternative', 'none'))
return f"Reason: {dep_docs['why']}\n\t{removal}Alternatives: {alt}"
ansible_core-2.19.0b4/lib/ansible/constants.py 0000644 0000000 0000000 00000017465 15010426755 020007 0 ustar 00root root # Copyright: (c) 2012-2014, Michael DeHaan
# Copyright: (c) 2017, Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import annotations
import re
from string import ascii_letters, digits
from ansible.config.manager import ConfigManager
from ansible.module_utils.common.text.converters import to_text
from ansible.module_utils.parsing.convert_bool import BOOLEANS_TRUE
from ansible.utils.fqcn import add_internal_fqcns
# initialize config manager/config data to read/store global settings
# and generate 'pseudo constants' for app consumption.
config = ConfigManager()
def set_constant(name, value, export=vars()):
""" sets constants and returns resolved options dict """
export[name] = value
# CONSTANTS ### yes, actual ones
# The following are hard-coded action names
_ACTION_DEBUG = add_internal_fqcns(('debug', ))
_ACTION_IMPORT_PLAYBOOK = add_internal_fqcns(('import_playbook', ))
_ACTION_IMPORT_ROLE = add_internal_fqcns(('import_role', ))
_ACTION_IMPORT_TASKS = add_internal_fqcns(('import_tasks', ))
_ACTION_INCLUDE_ROLE = add_internal_fqcns(('include_role', ))
_ACTION_INCLUDE_TASKS = add_internal_fqcns(('include_tasks', ))
_ACTION_INCLUDE_VARS = add_internal_fqcns(('include_vars', ))
_ACTION_INVENTORY_TASKS = add_internal_fqcns(('add_host', 'group_by'))
_ACTION_META = add_internal_fqcns(('meta', ))
_ACTION_SET_FACT = add_internal_fqcns(('set_fact', ))
_ACTION_SETUP = add_internal_fqcns(('setup', ))
_ACTION_HAS_CMD = add_internal_fqcns(('command', 'shell', 'script'))
_ACTION_ALLOWS_RAW_ARGS = _ACTION_HAS_CMD + add_internal_fqcns(('raw', ))
_ACTION_ALL_INCLUDES = _ACTION_INCLUDE_TASKS + _ACTION_INCLUDE_ROLE
_ACTION_ALL_INCLUDE_IMPORT_TASKS = _ACTION_INCLUDE_TASKS + _ACTION_IMPORT_TASKS
_ACTION_ALL_PROPER_INCLUDE_IMPORT_ROLES = _ACTION_INCLUDE_ROLE + _ACTION_IMPORT_ROLE
_ACTION_ALL_PROPER_INCLUDE_IMPORT_TASKS = _ACTION_INCLUDE_TASKS + _ACTION_IMPORT_TASKS
_ACTION_ALL_INCLUDE_ROLE_TASKS = _ACTION_INCLUDE_ROLE + _ACTION_INCLUDE_TASKS
_ACTION_FACT_GATHERING = _ACTION_SETUP + add_internal_fqcns(('gather_facts', ))
_ACTION_WITH_CLEAN_FACTS = _ACTION_SET_FACT + _ACTION_INCLUDE_VARS
# http://nezzen.net/2008/06/23/colored-text-in-python-using-ansi-escape-sequences/
COLOR_CODES = {
'black': u'0;30', 'bright gray': u'0;37',
'blue': u'0;34', 'white': u'1;37',
'green': u'0;32', 'bright blue': u'1;34',
'cyan': u'0;36', 'bright green': u'1;32',
'red': u'0;31', 'bright cyan': u'1;36',
'purple': u'0;35', 'bright red': u'1;31',
'yellow': u'0;33', 'bright purple': u'1;35',
'dark gray': u'1;30', 'bright yellow': u'1;33',
'magenta': u'0;35', 'bright magenta': u'1;35',
'normal': u'0',
}
REJECT_EXTS = ['.pyc', '.pyo', '.swp', '.bak', '~', '.rpm', '.md', '.txt', '.rst'] # this is concatenated with other config settings as lists; cannot be tuple
BOOL_TRUE = BOOLEANS_TRUE
COLLECTION_PTYPE_COMPAT = {'module': 'modules'}
PYTHON_DOC_EXTENSIONS = ('.py',)
YAML_DOC_EXTENSIONS = ('.yml', '.yaml')
DOC_EXTENSIONS = PYTHON_DOC_EXTENSIONS + YAML_DOC_EXTENSIONS
DEFAULT_BECOME_PASS = None
DEFAULT_PASSWORD_CHARS = to_text(ascii_letters + digits + ".,:-_", errors='strict') # characters included in auto-generated passwords
DEFAULT_REMOTE_PASS = None
DEFAULT_SUBSET = None
# FIXME: expand to other plugins, but never doc fragments
CONFIGURABLE_PLUGINS = ('become', 'cache', 'callback', 'cliconf', 'connection', 'httpapi', 'inventory', 'lookup', 'netconf', 'shell', 'vars')
# NOTE: always update the docs/docsite/Makefile to match
DOCUMENTABLE_PLUGINS = CONFIGURABLE_PLUGINS + ('module', 'strategy', 'test', 'filter')
IGNORE_FILES = ("COPYING", "CONTRIBUTING", "LICENSE", "README", "VERSION", "GUIDELINES", "MANIFEST", "Makefile") # ignore during module search
INTERNAL_RESULT_KEYS = ('add_host', 'add_group')
INTERNAL_STATIC_VARS = frozenset(
[
"ansible_async_path",
"ansible_collection_name",
"ansible_config_file",
"ansible_dependent_role_names",
"ansible_diff_mode",
"ansible_config_file",
"ansible_facts",
"ansible_forks",
"ansible_inventory_sources",
"ansible_limit",
"ansible_play_batch",
"ansible_play_hosts",
"ansible_play_hosts_all",
"ansible_play_role_names",
"ansible_playbook_python",
"ansible_role_name",
"ansible_role_names",
"ansible_run_tags",
"ansible_skip_tags",
"ansible_verbosity",
"ansible_version",
"inventory_dir",
"inventory_file",
"inventory_hostname",
"inventory_hostname_short",
"groups",
"group_names",
"hostvars",
"playbook_dir",
"play_hosts",
"role_name",
"role_names",
"role_path",
"role_uuid",
"role_names",
]
)
LOCALHOST = ('127.0.0.1', 'localhost', '::1')
WIN_MOVED = ['ansible.windows.win_command', 'ansible.windows.win_shell']
MODULE_REQUIRE_ARGS_SIMPLE = ['command', 'raw', 'script', 'shell', 'win_command', 'win_shell']
MODULE_REQUIRE_ARGS = tuple(add_internal_fqcns(MODULE_REQUIRE_ARGS_SIMPLE) + WIN_MOVED)
MODULE_NO_JSON = tuple(add_internal_fqcns(('command', 'win_command', 'shell', 'win_shell', 'raw')) + WIN_MOVED)
RESTRICTED_RESULT_KEYS = ('ansible_rsync_path', 'ansible_playbook_python', 'ansible_facts')
SYNTHETIC_COLLECTIONS = ('ansible.builtin', 'ansible.legacy')
TREE_DIR = None
VAULT_VERSION_MIN = 1.0
VAULT_VERSION_MAX = 1.0
# This matches a string that cannot be used as a valid python variable name i.e 'not-valid', 'not!valid@either' '1_nor_This'
INVALID_VARIABLE_NAMES = re.compile(r'^[\d\W]|[^\w]')
# FIXME: remove once play_context mangling is removed
# the magic variable mapping dictionary below is used to translate
# host/inventory variables to fields in the PlayContext
# object. The dictionary values are tuples, to account for aliases
# in variable names.
COMMON_CONNECTION_VARS = frozenset(('ansible_connection', 'ansible_host', 'ansible_user', 'ansible_shell_executable',
'ansible_port', 'ansible_pipelining', 'ansible_password', 'ansible_timeout',
'ansible_shell_type', 'ansible_module_compression', 'ansible_private_key_file'))
MAGIC_VARIABLE_MAPPING = dict(
# base
connection=('ansible_connection', ),
module_compression=('ansible_module_compression', ),
shell=('ansible_shell_type', ),
executable=('ansible_shell_executable', ),
# connection common
remote_addr=('ansible_ssh_host', 'ansible_host'),
remote_user=('ansible_ssh_user', 'ansible_user'),
password=('ansible_ssh_pass', 'ansible_password'),
port=('ansible_ssh_port', 'ansible_port'),
pipelining=('ansible_ssh_pipelining', 'ansible_pipelining'),
timeout=('ansible_ssh_timeout', 'ansible_timeout'),
private_key_file=('ansible_ssh_private_key_file', 'ansible_private_key_file'),
# networking modules
network_os=('ansible_network_os', ),
connection_user=('ansible_connection_user',),
# ssh TODO: remove
ssh_executable=('ansible_ssh_executable', ),
ssh_common_args=('ansible_ssh_common_args', ),
sftp_extra_args=('ansible_sftp_extra_args', ),
scp_extra_args=('ansible_scp_extra_args', ),
ssh_extra_args=('ansible_ssh_extra_args', ),
ssh_transfer_method=('ansible_ssh_transfer_method', ),
# docker TODO: remove
docker_extra_args=('ansible_docker_extra_args', ),
# become
become=('ansible_become', ),
become_method=('ansible_become_method', ),
become_user=('ansible_become_user', ),
become_pass=('ansible_become_password', 'ansible_become_pass'),
become_exe=('ansible_become_exe', ),
become_flags=('ansible_become_flags', ),
)
# POPULATE SETTINGS FROM CONFIG ###
for setting in config.get_configuration_definitions():
set_constant(setting, config.get_config_value(setting, variables=vars()))
ansible_core-2.19.0b4/lib/ansible/context.py 0000644 0000000 0000000 00000003615 15010426755 017447 0 ustar 00root root # Copyright: (c) 2018, Toshio Kuratomi
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
"""
Context of the running Ansible.
In the future we *may* create Context objects to allow running multiple Ansible plays in parallel
with different contexts but that is currently out of scope as the Ansible library is just for
running the ansible command line tools.
These APIs are still in flux so do not use them unless you are willing to update them with every Ansible release
"""
from __future__ import annotations
from collections.abc import Mapping, Set
from ansible.module_utils.common.collections import is_sequence
from ansible.utils.context_objects import CLIArgs, GlobalCLIArgs
__all__ = ('CLIARGS',)
# Note: this is not the singleton version. The Singleton is only created once the program has
# actually parsed the args
CLIARGS = CLIArgs({})
# This should be called immediately after cli_args are processed (parsed, validated, and any
# normalization performed on them). No other code should call it
def _init_global_context(cli_args):
"""Initialize the global context objects"""
global CLIARGS
CLIARGS = GlobalCLIArgs.from_options(cli_args)
def cliargs_deferred_get(key, default=None, shallowcopy=False):
"""Closure over getting a key from CLIARGS with shallow copy functionality
Primarily used in ``FieldAttribute`` where we need to defer setting the default
until after the CLI arguments have been parsed
This function is not directly bound to ``CliArgs`` so that it works with
``CLIARGS`` being replaced
"""
def inner():
value = CLIARGS.get(key, default=default)
if not shallowcopy:
return value
elif is_sequence(value):
return value[:]
elif isinstance(value, (Mapping, Set)):
return value.copy()
return value
return inner
ansible_core-2.19.0b4/lib/ansible/errors/ 0000755 0000000 0000000 00000000000 15010426755 016720 5 ustar 00root root ansible_core-2.19.0b4/lib/ansible/errors/__init__.py 0000644 0000000 0000000 00000037357 15010426755 021050 0 ustar 00root root # (c) 2012-2014, Michael DeHaan
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import annotations
import enum
import traceback
import sys
import types
import typing as t
from collections.abc import Sequence
from json import JSONDecodeError
from ansible.module_utils.common.text.converters import to_text
from ..module_utils.datatag import native_type_name
from ansible._internal._datatag import _tags
from .._internal._errors import _utils
if t.TYPE_CHECKING:
from ansible.plugins import loader as _t_loader
class ExitCode(enum.IntEnum):
SUCCESS = 0 # used by TQM, must be bit-flag safe
GENERIC_ERROR = 1 # used by TQM, must be bit-flag safe
HOST_FAILED = 2 # TQM-sourced, must be bit-flag safe
HOST_UNREACHABLE = 4 # TQM-sourced, must be bit-flag safe
PARSER_ERROR = 4 # FIXME: CLI-sourced, conflicts with HOST_UNREACHABLE
INVALID_CLI_OPTION = 5
UNICODE_ERROR = 6 # obsolete, no longer used
KEYBOARD_INTERRUPT = 99
UNKNOWN_ERROR = 250
class AnsibleError(Exception):
"""
This is the base class for all errors raised from Ansible code,
and can be instantiated with two optional parameters beyond the
error message to control whether detailed information is displayed
when the error occurred while parsing a data file of some kind.
Usage:
raise AnsibleError('some message here', obj=obj)
Where "obj" may be tagged with Origin to provide context for error messages.
"""
_exit_code = ExitCode.GENERIC_ERROR
_default_message = ''
_default_help_text: str | None = None
_include_cause_message = True
"""
When `True`, the exception message will be augmented with cause message(s).
Subclasses doing complex error analysis can disable this to take responsibility for reporting cause messages as needed.
"""
def __init__(
self,
message: str = "",
obj: t.Any = None,
show_content: bool = True,
suppress_extended_error: bool | types.EllipsisType = ...,
orig_exc: BaseException | None = None,
help_text: str | None = None,
) -> None:
# DTFIX-FUTURE: these fallback cases mask incorrect use of AnsibleError.message, what should we do?
if message is None:
message = ''
elif not isinstance(message, str):
message = str(message)
if self._default_message and message:
message = _utils.concat_message(self._default_message, message)
elif self._default_message:
message = self._default_message
elif not message:
message = f'Unexpected {type(self).__name__} error.'
super().__init__(message)
self._show_content = show_content
self._message = message
self._help_text_value = help_text or self._default_help_text
self.obj = obj
# deprecated: description='deprecate support for orig_exc, callers should use `raise ... from` only' core_version='2.23'
# deprecated: description='remove support for orig_exc' core_version='2.27'
self.orig_exc = orig_exc
if suppress_extended_error is not ...:
from ..utils.display import Display
if suppress_extended_error:
self._show_content = False
Display().deprecated(
msg=f"The `suppress_extended_error` argument to `{type(self).__name__}` is deprecated. Use `show_content=False` instead.",
version="2.23",
)
@property
def _original_message(self) -> str:
return self._message
@property
def message(self) -> str:
"""
If `include_cause_message` is False, return the original message.
Otherwise, return the original message with cause message(s) appended, stopping on (and including) the first non-AnsibleError.
The recursion is due to `AnsibleError.__str__` calling this method, which uses `str` on child exceptions to create the cause message.
Recursion stops on the first non-AnsibleError since those exceptions do not implement the custom `__str__` behavior.
"""
return _utils.get_chained_message(self)
@message.setter
def message(self, val) -> None:
self._message = val
@property
def _formatted_source_context(self) -> str | None:
with _utils.RedactAnnotatedSourceContext.when(not self._show_content):
if source_context := _utils.SourceContext.from_value(self.obj):
return str(source_context)
return None
@property
def _help_text(self) -> str | None:
return self._help_text_value
@_help_text.setter
def _help_text(self, value: str | None) -> None:
self._help_text_value = value
def __str__(self) -> str:
return self.message
def __getstate__(self) -> dict[str, t.Any]:
"""Augment object.__getstate__ to preserve additional values not represented in BaseException.__dict__."""
state = t.cast(dict[str, t.Any], super().__getstate__())
state.update(
args=self.args,
__cause__=self.__cause__,
__context__=self.__context__,
__suppress_context__=self.__suppress_context__,
)
return state
def __reduce__(self) -> tuple[t.Callable, tuple[type], dict[str, t.Any]]:
"""
Enable copy/pickle of AnsibleError derived types by correcting for BaseException's ancient C __reduce__ impl that:
* requires use of a type constructor with positional args
* assumes positional args are passed through from the derived type __init__ to BaseException.__init__ unmodified
* does not propagate args/__cause__/__context__/__suppress_context__
NOTE: This does not preserve the dunder attributes on non-AnsibleError derived cause/context exceptions.
As a result, copy/pickle will discard chained exceptions after the first non-AnsibleError cause/context.
"""
return type(self).__new__, (type(self),), self.__getstate__()
class AnsibleUndefinedConfigEntry(AnsibleError):
"""The requested config entry is not defined."""
class AnsibleTaskError(AnsibleError):
"""Task execution failed; provides contextual information about the task."""
_default_message = 'Task failed.'
class AnsiblePromptInterrupt(AnsibleError):
"""User interrupt."""
class AnsiblePromptNoninteractive(AnsibleError):
"""Unable to get user input."""
class AnsibleAssertionError(AnsibleError, AssertionError):
"""Invalid assertion."""
class AnsibleOptionsError(AnsibleError):
"""Invalid options were passed."""
# FIXME: This exception is used for many non-CLI related errors.
# The few cases which are CLI related should really be handled by argparse instead, at which point the exit code here can be removed.
_exit_code = ExitCode.INVALID_CLI_OPTION
class AnsibleRequiredOptionError(AnsibleOptionsError):
"""Bad or incomplete options passed."""
class AnsibleParserError(AnsibleError):
"""A playbook or data file could not be parsed."""
_exit_code = ExitCode.PARSER_ERROR
class AnsibleFieldAttributeError(AnsibleParserError):
"""Errors caused during field attribute processing."""
class AnsibleJSONParserError(AnsibleParserError):
"""JSON-specific parsing failure wrapping an exception raised by the JSON parser."""
_default_message = 'JSON parsing failed.'
_include_cause_message = False # hide the underlying cause message, it's included by `handle_exception` as needed
@classmethod
def handle_exception(cls, exception: Exception, origin: _tags.Origin) -> t.NoReturn:
if isinstance(exception, JSONDecodeError):
origin = origin.replace(line_num=exception.lineno, col_num=exception.colno)
message = str(exception)
error = cls(message, obj=origin)
raise error from exception
class AnsibleInternalError(AnsibleError):
"""Internal safeguards tripped, something happened in the code that should never happen."""
class AnsibleRuntimeError(AnsibleError):
"""Ansible had a problem while running a playbook."""
class AnsibleModuleError(AnsibleRuntimeError):
"""A module failed somehow."""
class AnsibleConnectionFailure(AnsibleRuntimeError):
"""The transport / connection_plugin had a fatal error."""
class AnsibleAuthenticationFailure(AnsibleConnectionFailure):
"""Invalid username/password/key."""
_default_message = "Failed to authenticate."
class AnsibleCallbackError(AnsibleRuntimeError):
"""A callback failure."""
class AnsibleTemplateError(AnsibleRuntimeError):
"""A template related error."""
class TemplateTrustCheckFailedError(AnsibleTemplateError):
"""Raised when processing was requested on an untrusted template or expression."""
_default_message = 'Encountered untrusted template or expression.'
_default_help_text = ('Templates and expressions must be defined by trusted sources such as playbooks or roles, '
'not untrusted sources such as module results.')
class AnsibleTemplateTransformLimitError(AnsibleTemplateError):
"""The internal template transform limit was exceeded."""
_default_message = "Template transform limit exceeded."
class AnsibleTemplateSyntaxError(AnsibleTemplateError):
"""A syntax error was encountered while parsing a Jinja template or expression."""
class AnsibleBrokenConditionalError(AnsibleTemplateError):
"""A broken conditional with non-boolean result was used."""
_default_help_text = 'Broken conditionals can be temporarily allowed with the `ALLOW_BROKEN_CONDITIONALS` configuration option.'
class AnsibleUndefinedVariable(AnsibleTemplateError):
"""An undefined variable was encountered while processing a template or expression."""
class AnsibleValueOmittedError(AnsibleTemplateError):
"""
Raised when the result of a template operation was the Omit singleton. This exception purposely does
not derive from AnsibleError to avoid elision of the traceback, since uncaught errors of this type always
indicate a bug.
"""
_default_message = "A template was resolved to an Omit scalar."
_default_help_text = "Callers must be prepared to handle this value. This is most likely a bug in the code requesting templating."
class AnsibleTemplatePluginError(AnsibleTemplateError):
"""An error sourced by a template plugin (lookup/filter/test)."""
# deprecated: description='add deprecation warnings for these aliases' core_version='2.23'
AnsibleFilterError = AnsibleTemplatePluginError
AnsibleLookupError = AnsibleTemplatePluginError
class AnsibleFileNotFound(AnsibleRuntimeError):
"""A file missing failure."""
def __init__(self, message="", obj=None, show_content=True, suppress_extended_error=..., orig_exc=None, paths=None, file_name=None):
self.file_name = file_name
self.paths = paths
if message:
message += "\n"
if self.file_name:
message += "Could not find or access '%s'" % to_text(self.file_name)
else:
message += "Could not find file"
if self.paths and isinstance(self.paths, Sequence):
searched = to_text('\n\t'.join(self.paths))
if message:
message += "\n"
message += "Searched in:\n\t%s" % searched
message += " on the Ansible Controller.\nIf you are using a module and expect the file to exist on the remote, see the remote_src option"
super(AnsibleFileNotFound, self).__init__(message=message, obj=obj, show_content=show_content,
suppress_extended_error=suppress_extended_error, orig_exc=orig_exc)
# These Exceptions are temporary, using them as flow control until we can get a better solution.
# DO NOT USE as they will probably be removed soon.
# We will port the action modules in our tree to use a context manager instead.
class AnsibleAction(AnsibleRuntimeError):
"""Base Exception for Action plugin flow control."""
def __init__(self, message="", obj=None, show_content=True, suppress_extended_error=..., orig_exc=None, result=None):
super(AnsibleAction, self).__init__(message=message, obj=obj, show_content=show_content,
suppress_extended_error=suppress_extended_error, orig_exc=orig_exc)
if result is None:
self.result = {}
else:
self.result = result
class AnsibleActionSkip(AnsibleAction):
"""An action runtime skip."""
def __init__(self, message="", obj=None, show_content=True, suppress_extended_error=..., orig_exc=None, result=None):
super(AnsibleActionSkip, self).__init__(message=message, obj=obj, show_content=show_content,
suppress_extended_error=suppress_extended_error, orig_exc=orig_exc, result=result)
self.result.update({'skipped': True, 'msg': message})
class AnsibleActionFail(AnsibleAction):
"""An action runtime failure."""
def __init__(self, message="", obj=None, show_content=True, suppress_extended_error=..., orig_exc=None, result=None):
super(AnsibleActionFail, self).__init__(message=message, obj=obj, show_content=show_content,
suppress_extended_error=suppress_extended_error, orig_exc=orig_exc, result=result)
result_overrides = {'failed': True, 'msg': message}
# deprecated: description='use sys.exception()' python_version='3.11'
if sys.exc_info()[1]: # DTFIX-RELEASE: remove this hack once TaskExecutor is no longer shucking AnsibleActionFail and returning its result
result_overrides['exception'] = traceback.format_exc()
self.result.update(result_overrides)
class _AnsibleActionDone(AnsibleAction):
"""An action runtime early exit."""
class AnsiblePluginError(AnsibleError):
"""Base class for Ansible plugin-related errors that do not need AnsibleError contextual data."""
def __init__(self, message: str | None = None, plugin_load_context: _t_loader.PluginLoadContext | None = None, help_text: str | None = None) -> None:
super(AnsiblePluginError, self).__init__(message, help_text=help_text)
self.plugin_load_context = plugin_load_context
class AnsiblePluginRemovedError(AnsiblePluginError):
"""A requested plugin has been removed."""
class AnsiblePluginCircularRedirect(AnsiblePluginError):
"""A cycle was detected in plugin redirection."""
class AnsibleCollectionUnsupportedVersionError(AnsiblePluginError):
"""A collection is not supported by this version of Ansible."""
class AnsibleTypeError(AnsibleRuntimeError, TypeError):
"""Ansible-augmented TypeError subclass."""
class AnsiblePluginNotFound(AnsiblePluginError):
"""Indicates we did not find an Ansible plugin."""
class AnsibleConditionalError(AnsibleRuntimeError):
"""Errors related to failed conditional expression evaluation."""
class AnsibleVariableTypeError(AnsibleRuntimeError):
"""An error due to attempted storage of an unsupported variable type."""
@classmethod
def from_value(cls, *, obj: t.Any) -> t.Self:
# avoid an incorrect error message when `obj` is a type
type_name = type(obj).__name__ if isinstance(obj, type) else native_type_name(obj)
return cls(message=f'Type {type_name!r} is unsupported for variable storage.', obj=obj)
def __getattr__(name: str) -> t.Any:
"""Inject import-time deprecation warnings."""
from ..utils.display import Display
if name == 'AnsibleFilterTypeError':
Display().deprecated(
msg="Importing 'AnsibleFilterTypeError' is deprecated.",
help_text=f"Import {AnsibleTypeError.__name__!r} instead.",
version="2.23",
)
return AnsibleTypeError
raise AttributeError(f'module {__name__!r} has no attribute {name!r}')
ansible_core-2.19.0b4/lib/ansible/executor/ 0000755 0000000 0000000 00000000000 15010426755 017242 5 ustar 00root root ansible_core-2.19.0b4/lib/ansible/executor/__init__.py 0000644 0000000 0000000 00000001355 15010426755 021357 0 ustar 00root root # (c) 2012-2014, Michael DeHaan
#
# 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 .
from __future__ import annotations
ansible_core-2.19.0b4/lib/ansible/executor/discovery/ 0000755 0000000 0000000 00000000000 15010426755 021251 5 ustar 00root root ansible_core-2.19.0b4/lib/ansible/executor/discovery/__init__.py 0000644 0000000 0000000 00000000000 15010426755 023350 0 ustar 00root root ansible_core-2.19.0b4/lib/ansible/executor/interpreter_discovery.py 0000644 0000000 0000000 00000007422 15010426755 024253 0 ustar 00root root # Copyright: (c) 2018 Ansible Project
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import annotations
import re
from ansible import constants as C
from ansible.errors import AnsibleError
from ansible.utils.display import Display
from ansible.utils.plugin_docs import get_versioned_doclink
_FALLBACK_INTERPRETER = '/usr/bin/python3'
display = Display()
foundre = re.compile(r'FOUND(.*)ENDFOUND', flags=re.DOTALL)
class InterpreterDiscoveryRequiredError(Exception):
def __init__(self, message, interpreter_name, discovery_mode):
super(InterpreterDiscoveryRequiredError, self).__init__(message)
self.interpreter_name = interpreter_name
self.discovery_mode = discovery_mode
def discover_interpreter(action, interpreter_name, discovery_mode, task_vars):
"""Probe the target host for a Python interpreter from the `INTERPRETER_PYTHON_FALLBACK` list, returning the first found or `/usr/bin/python3` if none."""
host = task_vars.get('inventory_hostname', 'unknown')
res = None
found_interpreters = [_FALLBACK_INTERPRETER] # fallback value
is_silent = discovery_mode.endswith('_silent')
if discovery_mode.startswith('auto_legacy'):
display.deprecated(
msg=f"The '{discovery_mode}' option for 'INTERPRETER_PYTHON' now has the same effect as 'auto'.",
version='2.21',
)
try:
bootstrap_python_list = C.config.get_config_value('INTERPRETER_PYTHON_FALLBACK', variables=task_vars)
display.vvv(msg=f"Attempting {interpreter_name} interpreter discovery.", host=host)
# not all command -v impls accept a list of commands, so we have to call it once per python
command_list = ["command -v '%s'" % py for py in bootstrap_python_list]
shell_bootstrap = "echo FOUND; {0}; echo ENDFOUND".format('; '.join(command_list))
# FUTURE: in most cases we probably don't want to use become, but maybe sometimes we do?
res = action._low_level_execute_command(shell_bootstrap, sudoable=False)
raw_stdout = res.get('stdout', u'')
match = foundre.match(raw_stdout)
if not match:
display.debug(u'raw interpreter discovery output: {0}'.format(raw_stdout), host=host)
raise ValueError('unexpected output from Python interpreter discovery')
found_interpreters = [interp.strip() for interp in match.groups()[0].splitlines() if interp.startswith('/')]
display.debug(u"found interpreters: {0}".format(found_interpreters), host=host)
if not found_interpreters:
if not is_silent:
display.warning(msg=f'No python interpreters found for host {host!r} (tried {bootstrap_python_list!r}).')
# this is lame, but returning None or throwing an exception is uglier
return _FALLBACK_INTERPRETER
except AnsibleError:
raise
except Exception as ex:
if not is_silent:
display.error_as_warning(msg=f'Unhandled error in Python interpreter discovery for host {host!r}.', exception=ex)
if res and res.get('stderr'): # the current ssh plugin implementation always has stderr, making coverage of the false case difficult
display.vvv(msg=f"Interpreter discovery remote stderr:\n{res.get('stderr')}", host=host)
if not is_silent:
display.warning(
msg=(
f"Host {host!r} is using the discovered Python interpreter at {found_interpreters[0]!r}, "
"but future installation of another Python interpreter could cause a different interpreter to be discovered."
),
help_text=f"See {get_versioned_doclink('reference_appendices/interpreter_discovery.html')} for more information.",
)
return found_interpreters[0]
ansible_core-2.19.0b4/lib/ansible/executor/module_common.py 0000644 0000000 0000000 00000164050 15010426755 022457 0 ustar 00root root # (c) 2013-2014, Michael DeHaan
# (c) 2015 Toshio Kuratomi
#
# 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 .
from __future__ import annotations
import ast
import base64
import dataclasses
import datetime
import json
import os
import pathlib
import pickle
import shlex
import zipfile
import re
import pkgutil
import types
import typing as t
from ast import AST, Import, ImportFrom
from io import BytesIO
from ansible._internal import _locking
from ansible._internal._datatag import _utils
from ansible.module_utils._internal import _dataclass_validation
from ansible.module_utils.common.yaml import yaml_load
from ansible._internal._datatag._tags import Origin
from ansible.module_utils.common.json import Direction, get_module_encoder
from ansible.release import __version__, __author__
from ansible import constants as C
from ansible.errors import AnsibleError
from ansible.executor.interpreter_discovery import InterpreterDiscoveryRequiredError
from ansible.executor.powershell import module_manifest as ps_manifest
from ansible.module_utils.common.text.converters import to_bytes, to_text, to_native
from ansible.plugins.become import BecomeBase
from ansible.plugins.loader import module_utils_loader
from ansible._internal._templating._engine import TemplateOptions, TemplateEngine
from ansible.template import Templar
from ansible.utils.collection_loader._collection_finder import _get_collection_metadata, _nested_dict_get
from ansible.module_utils._internal import _json, _ansiballz
from ansible.module_utils import basic as _basic
from ansible.module_utils.common import messages as _messages
if t.TYPE_CHECKING:
from ansible import template as _template
from ansible.playbook.task import Task
from ansible.utils.display import Display
import importlib.util
import importlib.machinery
display = Display()
@dataclasses.dataclass(frozen=True, order=True)
class _ModuleUtilsProcessEntry:
"""Represents a module/module_utils item awaiting import analysis."""
name_parts: tuple[str, ...]
is_ambiguous: bool = False
child_is_redirected: bool = False
is_optional: bool = False
@classmethod
def from_module(cls, module: types.ModuleType, append: str | None = None) -> t.Self:
name = module.__name__
if append:
name += '.' + append
return cls.from_module_name(name)
@classmethod
def from_module_name(cls, module_name: str) -> t.Self:
return cls(tuple(module_name.split('.')))
REPLACER = b"#<>"
REPLACER_VERSION = b"\"<>\""
REPLACER_COMPLEX = b"\"<>\""
REPLACER_WINDOWS = b"# POWERSHELL_COMMON"
REPLACER_JSONARGS = b"<>"
REPLACER_SELINUX = b"<>"
# module_common is relative to module_utils, so fix the path
_MODULE_UTILS_PATH = os.path.join(os.path.dirname(__file__), '..', 'module_utils')
_SHEBANG_PLACEHOLDER = '# shebang placeholder'
# ******************************************************************************
def _strip_comments(source: str) -> str:
# Strip comments and blank lines from the wrapper
buf = []
for line in source.splitlines():
l = line.strip()
if (not l or l.startswith('#')) and l != _SHEBANG_PLACEHOLDER:
line = ''
buf.append(line)
return '\n'.join(buf)
def _read_ansiballz_code() -> str:
code = (pathlib.Path(__file__).parent.parent / '_internal/_ansiballz.py').read_text()
if not C.DEFAULT_KEEP_REMOTE_FILES:
# Keep comments when KEEP_REMOTE_FILES is set. That way users will see
# the comments with some nice usage instructions.
# Otherwise, strip comments for smaller over the wire size.
code = _strip_comments(code)
return code
_ANSIBALLZ_CODE = _read_ansiballz_code() # read during startup to prevent individual workers from doing so
def _get_ansiballz_code(shebang: str) -> str:
code = _ANSIBALLZ_CODE
code = code.replace(_SHEBANG_PLACEHOLDER, shebang)
return code
# dirname(dirname(dirname(site-packages/ansible/executor/module_common.py) == site-packages
# Do this instead of getting site-packages from distutils.sysconfig so we work when we
# haven't been installed
site_packages = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
CORE_LIBRARY_PATH_RE = re.compile(r'%s/(?Pansible/modules/.*)\.(py|ps1)$' % re.escape(site_packages))
COLLECTION_PATH_RE = re.compile(r'/(?Pansible_collections/[^/]+/[^/]+/plugins/modules/.*)\.(py|ps1)$')
# Detect new-style Python modules by looking for required imports:
# import ansible_collections.[my_ns.my_col.plugins.module_utils.my_module_util]
# from ansible_collections.[my_ns.my_col.plugins.module_utils import my_module_util]
# import ansible.module_utils[.basic]
# from ansible.module_utils[ import basic]
# from ansible.module_utils[.basic import AnsibleModule]
# from ..module_utils[ import basic]
# from ..module_utils[.basic import AnsibleModule]
NEW_STYLE_PYTHON_MODULE_RE = re.compile(
# Relative imports
br'(?:from +\.{2,} *module_utils.* +import |'
# Collection absolute imports:
br'from +ansible_collections\.[^.]+\.[^.]+\.plugins\.module_utils.* +import |'
br'import +ansible_collections\.[^.]+\.[^.]+\.plugins\.module_utils.*|'
# Core absolute imports
br'from +ansible\.module_utils.* +import |'
br'import +ansible\.module_utils\.)'
)
class ModuleDepFinder(ast.NodeVisitor):
# DTFIX-RELEASE: add support for ignoring imports with a "controller only" comment, this will allow replacing import_controller_module with standard imports
def __init__(self, module_fqn, tree, is_pkg_init=False, *args, **kwargs):
"""
Walk the ast tree for the python module.
:arg module_fqn: The fully qualified name to reach this module in dotted notation.
example: ansible.module_utils.basic
:arg is_pkg_init: Inform the finder it's looking at a package init (eg __init__.py) to allow
relative import expansion to use the proper package level without having imported it locally first.
Save submodule[.submoduleN][.identifier] into self.submodules
when they are from ansible.module_utils or ansible_collections packages
self.submodules will end up with tuples like:
- ('ansible', 'module_utils', 'basic',)
- ('ansible', 'module_utils', 'urls', 'fetch_url')
- ('ansible', 'module_utils', 'database', 'postgres')
- ('ansible', 'module_utils', 'database', 'postgres', 'quote')
- ('ansible', 'module_utils', 'database', 'postgres', 'quote')
- ('ansible_collections', 'my_ns', 'my_col', 'plugins', 'module_utils', 'foo')
It's up to calling code to determine whether the final element of the
tuple are module names or something else (function, class, or variable names)
.. seealso:: :python3:class:`ast.NodeVisitor`
"""
super(ModuleDepFinder, self).__init__(*args, **kwargs)
self._tree = tree # squirrel this away so we can compare node parents to it
self.submodules = set()
self.optional_imports = set()
self.module_fqn = module_fqn
self.is_pkg_init = is_pkg_init
self._visit_map = {
Import: self.visit_Import,
ImportFrom: self.visit_ImportFrom,
}
self.visit(tree)
def generic_visit(self, node):
"""Overridden ``generic_visit`` that makes some assumptions about our
use case, and improves performance by calling visitors directly instead
of calling ``visit`` to offload calling visitors.
"""
generic_visit = self.generic_visit
visit_map = self._visit_map
for field, value in ast.iter_fields(node):
if isinstance(value, list):
for item in value:
if isinstance(item, (Import, ImportFrom)):
item.parent = node
visit_map[item.__class__](item)
elif isinstance(item, AST):
generic_visit(item)
visit = generic_visit
def visit_Import(self, node):
"""
Handle import ansible.module_utils.MODLIB[.MODLIBn] [as asname]
We save these as interesting submodules when the imported library is in ansible.module_utils
or ansible.collections
"""
for alias in node.names:
if (alias.name.startswith('ansible.module_utils.') or
alias.name.startswith('ansible_collections.')):
py_mod = tuple(alias.name.split('.'))
self.submodules.add(py_mod)
# if the import's parent is the root document, it's a required import, otherwise it's optional
if node.parent != self._tree:
self.optional_imports.add(py_mod)
self.generic_visit(node)
def visit_ImportFrom(self, node):
"""
Handle from ansible.module_utils.MODLIB import [.MODLIBn] [as asname]
Also has to handle relative imports
We save these as interesting submodules when the imported library is in ansible.module_utils
or ansible.collections
"""
# FIXME: These should all get skipped:
# from ansible.executor import module_common
# from ...executor import module_common
# from ... import executor (Currently it gives a non-helpful error)
if node.level > 0:
# if we're in a package init, we have to add one to the node level (and make it none if 0 to preserve the right slicing behavior)
level_slice_offset = -node.level + 1 or None if self.is_pkg_init else -node.level
if self.module_fqn:
parts = tuple(self.module_fqn.split('.'))
if node.module:
# relative import: from .module import x
node_module = '.'.join(parts[:level_slice_offset] + (node.module,))
else:
# relative import: from . import x
node_module = '.'.join(parts[:level_slice_offset])
else:
# fall back to an absolute import
node_module = node.module
else:
# absolute import: from module import x
node_module = node.module
# Specialcase: six is a special case because of its
# import logic
py_mod = None
if node.names[0].name == '_six':
self.submodules.add(('_six',))
elif node_module.startswith('ansible.module_utils'):
# from ansible.module_utils.MODULE1[.MODULEn] import IDENTIFIER [as asname]
# from ansible.module_utils.MODULE1[.MODULEn] import MODULEn+1 [as asname]
# from ansible.module_utils.MODULE1[.MODULEn] import MODULEn+1 [,IDENTIFIER] [as asname]
# from ansible.module_utils import MODULE1 [,MODULEn] [as asname]
py_mod = tuple(node_module.split('.'))
elif node_module.startswith('ansible_collections.'):
if node_module.endswith('plugins.module_utils') or '.plugins.module_utils.' in node_module:
# from ansible_collections.ns.coll.plugins.module_utils import MODULE [as aname] [,MODULE2] [as aname]
# from ansible_collections.ns.coll.plugins.module_utils.MODULE import IDENTIFIER [as aname]
# FIXME: Unhandled cornercase (needs to be ignored):
# from ansible_collections.ns.coll.plugins.[!module_utils].[FOO].plugins.module_utils import IDENTIFIER
py_mod = tuple(node_module.split('.'))
else:
# Not from module_utils so ignore. for instance:
# from ansible_collections.ns.coll.plugins.lookup import IDENTIFIER
pass
if py_mod:
for alias in node.names:
self.submodules.add(py_mod + (alias.name,))
# if the import's parent is the root document, it's a required import, otherwise it's optional
if node.parent != self._tree:
self.optional_imports.add(py_mod + (alias.name,))
self.generic_visit(node)
def _slurp(path):
if not os.path.exists(path):
raise AnsibleError("imported module support code does not exist at %s" % os.path.abspath(path))
with open(path, 'rb') as fd:
data = fd.read()
return data
def _get_shebang(interpreter, task_vars, templar: _template.Templar, args=tuple(), remote_is_local=False):
"""
Handles the different ways ansible allows overriding the shebang target for a module.
"""
# FUTURE: add logical equivalence for python3 in the case of py3-only modules
interpreter_name = os.path.basename(interpreter).strip()
# name for interpreter var
interpreter_config = u'ansible_%s_interpreter' % interpreter_name
# key for config
interpreter_config_key = "INTERPRETER_%s" % interpreter_name.upper()
interpreter_out = None
# looking for python, rest rely on matching vars
if interpreter_name == 'python':
# skip detection for network os execution, use playbook supplied one if possible
if remote_is_local:
interpreter_out = task_vars['ansible_playbook_python']
# a config def exists for this interpreter type; consult config for the value
elif C.config.get_configuration_definition(interpreter_config_key):
interpreter_from_config = C.config.get_config_value(interpreter_config_key, variables=task_vars)
interpreter_out = templar._engine.template(_utils.str_problematic_strip(interpreter_from_config),
options=TemplateOptions(value_for_omit=C.config.get_config_default(interpreter_config_key)))
# handle interpreter discovery if requested or empty interpreter was provided
if not interpreter_out or interpreter_out in ['auto', 'auto_legacy', 'auto_silent', 'auto_legacy_silent']:
discovered_interpreter_config = u'discovered_interpreter_%s' % interpreter_name
facts_from_task_vars = task_vars.get('ansible_facts', {})
if discovered_interpreter_config not in facts_from_task_vars:
# interpreter discovery is desired, but has not been run for this host
raise InterpreterDiscoveryRequiredError("interpreter discovery needed", interpreter_name=interpreter_name, discovery_mode=interpreter_out)
else:
interpreter_out = facts_from_task_vars[discovered_interpreter_config]
else:
raise InterpreterDiscoveryRequiredError("interpreter discovery required", interpreter_name=interpreter_name, discovery_mode='auto_legacy')
elif interpreter_config in task_vars:
# for non python we consult vars for a possible direct override
interpreter_out = templar._engine.template(_utils.str_problematic_strip(task_vars.get(interpreter_config)),
options=TemplateOptions(value_for_omit=None))
if not interpreter_out:
# nothing matched(None) or in case someone configures empty string or empty intepreter
interpreter_out = interpreter
# set shebang
shebang = u'#!{0}'.format(interpreter_out)
if args:
shebang = shebang + u' ' + u' '.join(args)
return shebang, interpreter_out
class ModuleUtilLocatorBase:
def __init__(self, fq_name_parts, is_ambiguous=False, child_is_redirected=False, is_optional=False):
self._is_ambiguous = is_ambiguous
# a child package redirection could cause intermediate package levels to be missing, eg
# from ansible.module_utils.x.y.z import foo; if x.y.z.foo is redirected, we may not have packages on disk for
# the intermediate packages x.y.z, so we'll need to supply empty packages for those
self._child_is_redirected = child_is_redirected
self._is_optional = is_optional
self.found = False
self.redirected = False
self.fq_name_parts = fq_name_parts
self.source_code = ''
self.output_path = ''
self.is_package = False
self._collection_name = None
# for ambiguous imports, we should only test for things more than one level below module_utils
# this lets us detect erroneous imports and redirections earlier
if is_ambiguous and len(self._get_module_utils_remainder_parts(fq_name_parts)) > 1:
self.candidate_names = [fq_name_parts, fq_name_parts[:-1]]
else:
self.candidate_names = [fq_name_parts]
@property
def candidate_names_joined(self):
return ['.'.join(n) for n in self.candidate_names]
def _handle_redirect(self, name_parts):
module_utils_relative_parts = self._get_module_utils_remainder_parts(name_parts)
# only allow redirects from below module_utils- if above that, bail out (eg, parent package names)
if not module_utils_relative_parts:
return False
try:
collection_metadata = _get_collection_metadata(self._collection_name)
except ValueError as ve: # collection not found or some other error related to collection load
if self._is_optional:
return False
raise AnsibleError('error processing module_util {0} loading redirected collection {1}: {2}'
.format('.'.join(name_parts), self._collection_name, to_native(ve)))
routing_entry = _nested_dict_get(collection_metadata, ['plugin_routing', 'module_utils', '.'.join(module_utils_relative_parts)])
if not routing_entry:
return False
# FIXME: add deprecation warning support
dep_or_ts = routing_entry.get('tombstone')
removed = dep_or_ts is not None
if not removed:
dep_or_ts = routing_entry.get('deprecation')
if dep_or_ts:
removal_date = dep_or_ts.get('removal_date')
removal_version = dep_or_ts.get('removal_version')
warning_text = dep_or_ts.get('warning_text')
msg = 'module_util {0} has been removed'.format('.'.join(name_parts))
if warning_text:
msg += ' ({0})'.format(warning_text)
else:
msg += '.'
display.deprecated( # pylint: disable=ansible-deprecated-date-not-permitted,ansible-deprecated-unnecessary-collection-name
msg=msg,
version=removal_version,
removed=removed,
date=removal_date,
deprecator=_messages.PluginInfo._from_collection_name(self._collection_name),
)
if 'redirect' in routing_entry:
self.redirected = True
source_pkg = '.'.join(name_parts)
self.is_package = True # treat all redirects as packages
redirect_target_pkg = routing_entry['redirect']
# expand FQCN redirects
if not redirect_target_pkg.startswith('ansible_collections'):
split_fqcn = redirect_target_pkg.split('.')
if len(split_fqcn) < 3:
raise Exception('invalid redirect for {0}: {1}'.format(source_pkg, redirect_target_pkg))
# assume it's an FQCN, expand it
redirect_target_pkg = 'ansible_collections.{0}.{1}.plugins.module_utils.{2}'.format(
split_fqcn[0], # ns
split_fqcn[1], # coll
'.'.join(split_fqcn[2:]) # sub-module_utils remainder
)
display.vvv('redirecting module_util {0} to {1}'.format(source_pkg, redirect_target_pkg))
self.source_code = self._generate_redirect_shim_source(source_pkg, redirect_target_pkg)
return True
return False
def _get_module_utils_remainder_parts(self, name_parts):
# subclasses should override to return the name parts after module_utils
return []
def _get_module_utils_remainder(self, name_parts):
# return the remainder parts as a package string
return '.'.join(self._get_module_utils_remainder_parts(name_parts))
def _find_module(self, name_parts):
return False
def _locate(self, redirect_first=True):
for candidate_name_parts in self.candidate_names:
if redirect_first and self._handle_redirect(candidate_name_parts):
break
if self._find_module(candidate_name_parts):
break
if not redirect_first and self._handle_redirect(candidate_name_parts):
break
else: # didn't find what we were looking for- last chance for packages whose parents were redirected
if self._child_is_redirected: # make fake packages
self.is_package = True
self.source_code = ''
else: # nope, just bail
return
if self.is_package:
path_parts = candidate_name_parts + ('__init__',)
else:
path_parts = candidate_name_parts
self.found = True
self.output_path = os.path.join(*path_parts) + '.py'
self.fq_name_parts = candidate_name_parts
def _generate_redirect_shim_source(self, fq_source_module, fq_target_module):
return """
import sys
import {1} as mod
sys.modules['{0}'] = mod
""".format(fq_source_module, fq_target_module)
# FIXME: add __repr__ impl
class LegacyModuleUtilLocator(ModuleUtilLocatorBase):
def __init__(self, fq_name_parts, is_ambiguous=False, mu_paths=None, child_is_redirected=False):
super(LegacyModuleUtilLocator, self).__init__(fq_name_parts, is_ambiguous, child_is_redirected)
if fq_name_parts[0:2] != ('ansible', 'module_utils'):
raise Exception('this class can only locate from ansible.module_utils, got {0}'.format(fq_name_parts))
if fq_name_parts[2] == 'six':
# FIXME: handle the ansible.module_utils.six._six case with a redirect or an internal _six attr on six itself?
# six creates its submodules at runtime; convert all these to just 'ansible.module_utils.six'
fq_name_parts = ('ansible', 'module_utils', 'six')
self.candidate_names = [fq_name_parts]
self._mu_paths = mu_paths
self._collection_name = 'ansible.builtin' # legacy module utils always look in ansible.builtin for redirects
self._locate(redirect_first=False) # let local stuff override redirects for legacy
def _get_module_utils_remainder_parts(self, name_parts):
return name_parts[2:] # eg, foo.bar for ansible.module_utils.foo.bar
def _find_module(self, name_parts):
rel_name_parts = self._get_module_utils_remainder_parts(name_parts)
# no redirection; try to find the module
if len(rel_name_parts) == 1: # direct child of module_utils, just search the top-level dirs we were given
paths = self._mu_paths
else: # a nested submodule of module_utils, extend the paths given with the intermediate package names
paths = [os.path.join(p, *rel_name_parts[:-1]) for p in
self._mu_paths] # extend the MU paths with the relative bit
# find_spec needs the full module name
self._info = info = importlib.machinery.PathFinder.find_spec('.'.join(name_parts), paths)
if info is not None and info.origin is not None and os.path.splitext(info.origin)[1] in importlib.machinery.SOURCE_SUFFIXES:
self.is_package = info.origin.endswith('/__init__.py')
path = info.origin
else:
return False
self.source_code = Origin(path=path).tag(_slurp(path))
return True
class CollectionModuleUtilLocator(ModuleUtilLocatorBase):
def __init__(self, fq_name_parts, is_ambiguous=False, child_is_redirected=False, is_optional=False):
super(CollectionModuleUtilLocator, self).__init__(fq_name_parts, is_ambiguous, child_is_redirected, is_optional)
if fq_name_parts[0] != 'ansible_collections':
raise Exception('CollectionModuleUtilLocator can only locate from ansible_collections, got {0}'.format(fq_name_parts))
elif len(fq_name_parts) >= 6 and fq_name_parts[3:5] != ('plugins', 'module_utils'):
raise Exception('CollectionModuleUtilLocator can only locate below ansible_collections.(ns).(coll).plugins.module_utils, got {0}'
.format(fq_name_parts))
self._collection_name = '.'.join(fq_name_parts[1:3])
self._locate()
def _find_module(self, name_parts):
# synthesize empty inits for packages down through module_utils- we don't want to allow those to be shipped over, but the
# package hierarchy needs to exist
if len(name_parts) < 6:
self.source_code = ''
self.is_package = True
return True
# NB: we can't use pkgutil.get_data safely here, since we don't want to import/execute package/module code on
# the controller while analyzing/assembling the module, so we'll have to manually import the collection's
# Python package to locate it (import root collection, reassemble resource path beneath, fetch source)
collection_pkg_name = '.'.join(name_parts[0:3])
resource_base_path = os.path.join(*name_parts[3:])
src = None
# look for package_dir first, then module
src_path = to_native(os.path.join(resource_base_path, '__init__.py'))
try:
collection_pkg = importlib.import_module(collection_pkg_name)
pkg_path = os.path.dirname(collection_pkg.__file__)
except (ImportError, AttributeError):
pkg_path = None
try:
src = pkgutil.get_data(collection_pkg_name, src_path)
except ImportError:
pass
# TODO: we might want to synthesize fake inits for py3-style packages, for now they're required beneath module_utils
if src is not None: # empty string is OK
self.is_package = True
else:
src_path = to_native(resource_base_path + '.py')
try:
src = pkgutil.get_data(collection_pkg_name, src_path)
except ImportError:
pass
if src is None: # empty string is OK
return False
# TODO: this feels brittle and funky; we should be able to more definitively assure the source path
if pkg_path:
origin = Origin(path=os.path.join(pkg_path, src_path))
else:
# DTFIX-RELEASE: not sure if this case is even reachable
origin = Origin(description=f'')
self.source_code = origin.tag(src)
return True
def _get_module_utils_remainder_parts(self, name_parts):
return name_parts[5:] # eg, foo.bar for ansible_collections.ns.coll.plugins.module_utils.foo.bar
def _make_zinfo(filename: str, date_time: datetime.datetime, zf: zipfile.ZipFile | None = None) -> zipfile.ZipInfo:
zinfo = zipfile.ZipInfo(
filename=filename,
date_time=date_time.utctimetuple()[:6],
)
if zf:
zinfo.compress_type = zf.compression
return zinfo
@dataclasses.dataclass(frozen=True, kw_only=True, slots=True)
class ModuleMetadata:
@classmethod
def __post_init__(cls):
_dataclass_validation.inject_post_init_validation(cls)
@dataclasses.dataclass(frozen=True, kw_only=True, slots=True)
class ModuleMetadataV1(ModuleMetadata):
serialization_profile: str
metadata_versions: dict[t.Any, type[ModuleMetadata]] = {
1: ModuleMetadataV1,
}
def _get_module_metadata(module: ast.Module) -> ModuleMetadata:
# DTFIX-RELEASE: while module metadata works, this feature isn't fully baked and should be turned off before release
metadata_nodes: list[ast.Assign] = []
for node in module.body:
if isinstance(node, ast.Assign):
if len(node.targets) == 1:
target = node.targets[0]
if isinstance(target, ast.Name):
if target.id == 'METADATA':
metadata_nodes.append(node)
if not metadata_nodes:
return ModuleMetadataV1(
serialization_profile='legacy',
)
if len(metadata_nodes) > 1:
raise ValueError('Module METADATA must defined only once.')
metadata_node = metadata_nodes[0]
if not isinstance(metadata_node.value, ast.Constant):
raise TypeError(f'Module METADATA node must be {ast.Constant} not {type(metadata_node)}.')
unparsed_metadata = metadata_node.value.value
if not isinstance(unparsed_metadata, str):
raise TypeError(f'Module METADATA must be {str} not {type(unparsed_metadata)}.')
try:
parsed_metadata = yaml_load(unparsed_metadata)
except Exception as ex:
raise ValueError('Module METADATA must be valid YAML.') from ex
if not isinstance(parsed_metadata, dict):
raise TypeError(f'Module METADATA must parse to {dict} not {type(parsed_metadata)}.')
schema_version = parsed_metadata.pop('schema_version', None)
if not (metadata_type := metadata_versions.get(schema_version)):
raise ValueError(f'Module METADATA schema_version {schema_version} is unknown.')
try:
metadata = metadata_type(**parsed_metadata) # type: ignore
except Exception as ex:
raise ValueError('Module METADATA is invalid.') from ex
return metadata
def recursive_finder(name: str, module_fqn: str, module_data: str | bytes, zf: zipfile.ZipFile, date_time: datetime.datetime) -> ModuleMetadata:
"""
Using ModuleDepFinder, make sure we have all of the module_utils files that
the module and its module_utils files needs. (no longer actually recursive)
:arg name: Name of the python module we're examining
:arg module_fqn: Fully qualified name of the python module we're scanning
:arg module_data: string Python code of the module we're scanning
:arg zf: An open :python:class:`zipfile.ZipFile` object that holds the Ansible module payload
which we're assembling
"""
# py_module_cache maps python module names to a tuple of the code in the module
# and the pathname to the module.
# Here we pre-load it with modules which we create without bothering to
# read from actual files (In some cases, these need to differ from what ansible
# ships because they're namespace packages in the module)
# FIXME: do we actually want ns pkg behavior for these? Seems like they should just be forced to emptyish pkg stubs
py_module_cache = {
('ansible',): (
b'from pkgutil import extend_path\n'
b'__path__=extend_path(__path__,__name__)\n'
b'__version__="' + to_bytes(__version__) +
b'"\n__author__="' + to_bytes(__author__) + b'"\n',
'ansible/__init__.py'),
('ansible', 'module_utils'): (
b'from pkgutil import extend_path\n'
b'__path__=extend_path(__path__,__name__)\n',
'ansible/module_utils/__init__.py')}
module_utils_paths = [p for p in module_utils_loader._get_paths(subdirs=False) if os.path.isdir(p)]
module_utils_paths.append(_MODULE_UTILS_PATH)
tree = _compile_module_ast(name, module_data)
module_metadata = _get_module_metadata(tree)
finder = ModuleDepFinder(module_fqn, tree)
if not isinstance(module_metadata, ModuleMetadataV1):
raise NotImplementedError()
profile = module_metadata.serialization_profile
# the format of this set is a tuple of the module name and whether the import is ambiguous as a module name
# or an attribute of a module (e.g. from x.y import z <-- is z a module or an attribute of x.y?)
modules_to_process = [_ModuleUtilsProcessEntry(m, True, False, is_optional=m in finder.optional_imports) for m in finder.submodules]
# include module_utils that are always required
modules_to_process.extend((
_ModuleUtilsProcessEntry.from_module(_ansiballz),
_ModuleUtilsProcessEntry.from_module(_basic),
_ModuleUtilsProcessEntry.from_module_name(_json.get_module_serialization_profile_module_name(profile, True)),
_ModuleUtilsProcessEntry.from_module_name(_json.get_module_serialization_profile_module_name(profile, False)),
))
module_info: ModuleUtilLocatorBase
# we'll be adding new modules inline as we discover them, so just keep going til we've processed them all
while modules_to_process:
modules_to_process.sort() # not strictly necessary, but nice to process things in predictable and repeatable order
entry = modules_to_process.pop(0)
if entry.name_parts in py_module_cache:
# this is normal; we'll often see the same module imported many times, but we only need to process it once
continue
if entry.name_parts[0:2] == ('ansible', 'module_utils'):
module_info = LegacyModuleUtilLocator(entry.name_parts, is_ambiguous=entry.is_ambiguous,
mu_paths=module_utils_paths, child_is_redirected=entry.child_is_redirected)
elif entry.name_parts[0] == 'ansible_collections':
module_info = CollectionModuleUtilLocator(entry.name_parts, is_ambiguous=entry.is_ambiguous,
child_is_redirected=entry.child_is_redirected, is_optional=entry.is_optional)
else:
# FIXME: dot-joined result
display.warning('ModuleDepFinder improperly found a non-module_utils import %s'
% [entry.name_parts])
continue
# Could not find the module. Construct a helpful error message.
if not module_info.found:
if entry.is_optional:
# this was a best-effort optional import that we couldn't find, oh well, move along...
continue
# FIXME: use dot-joined candidate names
msg = 'Could not find imported module support code for {0}. Looked for ({1})'.format(module_fqn, module_info.candidate_names_joined)
raise AnsibleError(msg)
# check the cache one more time with the module we actually found, since the name could be different than the input
# eg, imported name vs module
if module_info.fq_name_parts in py_module_cache:
continue
tree = _compile_module_ast('.'.join(module_info.fq_name_parts), module_info.source_code)
finder = ModuleDepFinder('.'.join(module_info.fq_name_parts), tree, module_info.is_package)
modules_to_process.extend(_ModuleUtilsProcessEntry(m, True, False, is_optional=m in finder.optional_imports)
for m in finder.submodules if m not in py_module_cache)
# we've processed this item, add it to the output list
py_module_cache[module_info.fq_name_parts] = (module_info.source_code, module_info.output_path)
# ensure we process all ancestor package inits
accumulated_pkg_name = []
for pkg in module_info.fq_name_parts[:-1]:
accumulated_pkg_name.append(pkg) # we're accumulating this across iterations
normalized_name = tuple(accumulated_pkg_name) # extra machinations to get a hashable type (list is not)
if normalized_name not in py_module_cache:
modules_to_process.append(_ModuleUtilsProcessEntry(normalized_name, False, module_info.redirected, is_optional=entry.is_optional))
for py_module_name in py_module_cache:
py_module_file_name = py_module_cache[py_module_name][1]
zf.writestr(
_make_zinfo(py_module_file_name, date_time, zf=zf),
py_module_cache[py_module_name][0]
)
mu_file = to_text(py_module_file_name, errors='surrogate_or_strict')
display.vvvvv("Including module_utils file %s" % mu_file)
return module_metadata
def _compile_module_ast(module_name: str, source_code: str | bytes) -> ast.Module:
origin = Origin.get_tag(source_code) or Origin.UNKNOWN
# compile the source, process all relevant imported modules
try:
tree = t.cast(ast.Module, compile(source_code, str(origin), 'exec', ast.PyCF_ONLY_AST))
except SyntaxError as ex:
raise AnsibleError(f"Unable to compile {module_name!r}.", obj=origin.replace(line_num=ex.lineno, col_num=ex.offset)) from ex
return tree
def _is_binary(b_module_data):
"""Heuristic to classify a file as binary by sniffing a 1k header; see https://stackoverflow.com/a/7392391"""
textchars = bytearray(set([7, 8, 9, 10, 12, 13, 27]) | set(range(0x20, 0x100)) - set([0x7f]))
start = b_module_data[:1024]
return bool(start.translate(None, textchars))
def _get_ansible_module_fqn(module_path):
"""
Get the fully qualified name for an ansible module based on its pathname
remote_module_fqn is the fully qualified name. Like ansible.modules.system.ping
Or ansible_collections.Namespace.Collection_name.plugins.modules.ping
.. warning:: This function is for ansible modules only. It won't work for other things
(non-module plugins, etc)
"""
remote_module_fqn = None
# Is this a core module?
match = CORE_LIBRARY_PATH_RE.search(module_path)
if not match:
# Is this a module in a collection?
match = COLLECTION_PATH_RE.search(module_path)
# We can tell the FQN for core modules and collection modules
if match:
path = match.group('path')
if '.' in path:
# FQNs must be valid as python identifiers. This sanity check has failed.
# we could check other things as well
raise ValueError('Module name (or path) was not a valid python identifier')
remote_module_fqn = '.'.join(path.split('/'))
else:
# Currently we do not handle modules in roles so we can end up here for that reason
raise ValueError("Unable to determine module's fully qualified name")
return remote_module_fqn
def _add_module_to_zip(zf: zipfile.ZipFile, date_time: datetime.datetime, remote_module_fqn: str, b_module_data: bytes) -> None:
"""Add a module from ansible or from an ansible collection into the module zip"""
module_path_parts = remote_module_fqn.split('.')
# Write the module
module_path = '/'.join(module_path_parts) + '.py'
zf.writestr(
_make_zinfo(module_path, date_time, zf=zf),
b_module_data
)
existing_paths: frozenset[str]
# Write the __init__.py's necessary to get there
if module_path_parts[0] == 'ansible':
# The ansible namespace is setup as part of the module_utils setup...
start = 2
existing_paths = frozenset()
else:
# ... but ansible_collections and other toplevels are not
start = 1
existing_paths = frozenset(zf.namelist())
for idx in range(start, len(module_path_parts)):
package_path = '/'.join(module_path_parts[:idx]) + '/__init__.py'
# If a collections module uses module_utils from a collection then most packages will have already been added by recursive_finder.
if package_path in existing_paths:
continue
# Note: We don't want to include more than one ansible module in a payload at this time
# so no need to fill the __init__.py with namespace code
zf.writestr(
_make_zinfo(package_path, date_time, zf=zf),
b''
)
@dataclasses.dataclass(kw_only=True, slots=True, frozen=True)
class _BuiltModule:
"""Payload required to execute an Ansible module, along with information required to do so."""
b_module_data: bytes
module_style: t.Literal['binary', 'new', 'non_native_want_json', 'old']
shebang: str | None
serialization_profile: str
@dataclasses.dataclass(kw_only=True, slots=True, frozen=True)
class _CachedModule:
"""Cached Python module created by AnsiballZ."""
# DTFIX-RELEASE: secure this (locked down pickle, don't use pickle, etc.)
zip_data: bytes
metadata: ModuleMetadata
def dump(self, path: str) -> None:
temp_path = pathlib.Path(path + '-part')
with temp_path.open('wb') as cache_file:
pickle.dump(self, cache_file)
temp_path.rename(path)
@classmethod
def load(cls, path: str) -> t.Self:
with pathlib.Path(path).open('rb') as cache_file:
return pickle.load(cache_file)
def _find_module_utils(
*,
module_name: str,
b_module_data: bytes,
module_path: str,
module_args: dict[object, object],
task_vars: dict[str, object],
templar: Templar,
module_compression: str,
async_timeout: int,
become_plugin: BecomeBase | None,
environment: dict[str, str],
remote_is_local: bool = False
) -> _BuiltModule:
"""
Given the source of the module, convert it to a Jinja2 template to insert
module code and return whether it's a new or old style module.
"""
module_substyle: t.Literal['binary', 'jsonargs', 'non_native_want_json', 'old', 'powershell', 'python']
module_style: t.Literal['binary', 'new', 'non_native_want_json', 'old']
module_substyle = module_style = 'old'
# module_style is something important to calling code (ActionBase). It
# determines how arguments are formatted (json vs k=v) and whether
# a separate arguments file needs to be sent over the wire.
# module_substyle is extra information that's useful internally. It tells
# us what we have to look to substitute in the module files and whether
# we're using module replacer or ansiballz to format the module itself.
if _is_binary(b_module_data):
module_substyle = module_style = 'binary'
elif REPLACER in b_module_data:
# Do REPLACER before from ansible.module_utils because we need make sure
# we substitute "from ansible.module_utils basic" for REPLACER
module_style = 'new'
module_substyle = 'python'
b_module_data = b_module_data.replace(REPLACER, b'from ansible.module_utils.basic import *')
elif NEW_STYLE_PYTHON_MODULE_RE.search(b_module_data):
module_style = 'new'
module_substyle = 'python'
elif REPLACER_WINDOWS in b_module_data:
module_style = 'new'
module_substyle = 'powershell'
b_module_data = b_module_data.replace(REPLACER_WINDOWS, b'#AnsibleRequires -PowerShell Ansible.ModuleUtils.Legacy')
elif re.search(b'#Requires -Module', b_module_data, re.IGNORECASE) \
or re.search(b'#Requires -Version', b_module_data, re.IGNORECASE)\
or re.search(b'#AnsibleRequires -OSVersion', b_module_data, re.IGNORECASE) \
or re.search(b'#AnsibleRequires -Powershell', b_module_data, re.IGNORECASE) \
or re.search(b'#AnsibleRequires -CSharpUtil', b_module_data, re.IGNORECASE):
module_style = 'new'
module_substyle = 'powershell'
elif REPLACER_JSONARGS in b_module_data:
module_style = 'new'
module_substyle = 'jsonargs'
elif b'WANT_JSON' in b_module_data:
module_substyle = module_style = 'non_native_want_json'
shebang = None
# Neither old-style, non_native_want_json nor binary modules should be modified
# except for the shebang line (Done by modify_module)
if module_style in ('old', 'non_native_want_json', 'binary'):
return _BuiltModule(
b_module_data=b_module_data,
module_style=module_style,
shebang=shebang,
serialization_profile='legacy',
)
output = BytesIO()
try:
remote_module_fqn = _get_ansible_module_fqn(module_path)
except ValueError:
# Modules in roles currently are not found by the fqn heuristic so we
# fallback to this. This means that relative imports inside a module from
# a role may fail. Absolute imports should be used for future-proofness.
# People should start writing collections instead of modules in roles so we
# may never fix this
display.debug('ANSIBALLZ: Could not determine module FQN')
# FIXME: add integration test to validate that builtins and legacy modules with the same name are tracked separately by the caching mechanism
# FIXME: surrogate FQN should be unique per source path- role-packaged modules with name collisions can still be aliased
remote_module_fqn = 'ansible.legacy.%s' % module_name
if module_substyle == 'python':
date_time = datetime.datetime.now(datetime.timezone.utc)
if date_time.year < 1980:
raise AnsibleError(f'Cannot create zipfile due to pre-1980 configured date: {date_time}')
try:
compression_method = getattr(zipfile, module_compression)
except AttributeError:
display.warning(u'Bad module compression string specified: %s. Using ZIP_STORED (no compression)' % module_compression)
compression_method = zipfile.ZIP_STORED
lookup_path = os.path.join(C.DEFAULT_LOCAL_TMP, 'ansiballz_cache') # type: ignore[attr-defined]
cached_module_filename = os.path.join(lookup_path, "%s-%s" % (remote_module_fqn, module_compression))
os.makedirs(os.path.dirname(cached_module_filename), exist_ok=True)
zipdata: bytes | None = None
module_metadata: ModuleMetadata | None = None
# Optimization -- don't lock if the module has already been cached
if os.path.exists(cached_module_filename):
display.debug('ANSIBALLZ: using cached module: %s' % cached_module_filename)
cached_module = _CachedModule.load(cached_module_filename)
zipdata, module_metadata = cached_module.zip_data, cached_module.metadata
else:
display.debug('ANSIBALLZ: Acquiring lock')
lock_path = f'{cached_module_filename}.lock'
with _locking.named_mutex(lock_path):
display.debug(f'ANSIBALLZ: Lock acquired: {lock_path}')
# Check that no other process has created this while we were
# waiting for the lock
if not os.path.exists(cached_module_filename):
display.debug('ANSIBALLZ: Creating module')
# Create the module zip data
zipoutput = BytesIO()
zf = zipfile.ZipFile(zipoutput, mode='w', compression=compression_method)
# walk the module imports, looking for module_utils to send- they'll be added to the zipfile
module_metadata = recursive_finder(module_name, remote_module_fqn, Origin(path=module_path).tag(b_module_data), zf, date_time)
display.debug('ANSIBALLZ: Writing module into payload')
_add_module_to_zip(zf, date_time, remote_module_fqn, b_module_data)
zf.close()
zipdata = base64.b64encode(zipoutput.getvalue())
# Write the assembled module to a temp file (write to temp
# so that no one looking for the file reads a partially
# written file)
os.makedirs(lookup_path, exist_ok=True)
display.debug('ANSIBALLZ: Writing module')
cached_module = _CachedModule(zip_data=zipdata, metadata=module_metadata)
cached_module.dump(cached_module_filename)
display.debug('ANSIBALLZ: Done creating module')
if not zipdata:
display.debug('ANSIBALLZ: Reading module after lock')
# Another process wrote the file while we were waiting for
# the write lock. Go ahead and read the data from disk
# instead of re-creating it.
try:
cached_module = _CachedModule.load(cached_module_filename)
except IOError:
raise AnsibleError('A different worker process failed to create module file. '
'Look at traceback for that process for debugging information.')
zipdata, module_metadata = cached_module.zip_data, cached_module.metadata
o_interpreter, o_args = _extract_interpreter(b_module_data)
if o_interpreter is None:
o_interpreter = u'/usr/bin/python'
shebang, interpreter = _get_shebang(o_interpreter, task_vars, templar, o_args, remote_is_local=remote_is_local)
# FUTURE: the module cache entry should be invalidated if we got this value from a host-dependent source
rlimit_nofile = C.config.get_config_value('PYTHON_MODULE_RLIMIT_NOFILE', variables=task_vars)
if not isinstance(rlimit_nofile, int):
rlimit_nofile = int(templar._engine.template(rlimit_nofile, options=TemplateOptions(value_for_omit=0)))
coverage_config = os.environ.get('_ANSIBLE_COVERAGE_CONFIG')
if coverage_config:
coverage_output = os.environ['_ANSIBLE_COVERAGE_OUTPUT']
else:
coverage_output = None
if not isinstance(module_metadata, ModuleMetadataV1):
raise NotImplementedError()
params = dict(ANSIBLE_MODULE_ARGS=module_args,)
encoder = get_module_encoder(module_metadata.serialization_profile, Direction.CONTROLLER_TO_MODULE)
try:
encoded_params = json.dumps(params, cls=encoder)
except TypeError as ex:
raise AnsibleError(f'Failed to serialize arguments for the {module_name!r} module.') from ex
code = _get_ansiballz_code(shebang)
args = dict(
zipdata=to_text(zipdata),
ansible_module=module_name,
module_fqn=remote_module_fqn,
params=encoded_params,
profile=module_metadata.serialization_profile,
date_time=date_time,
coverage_config=coverage_config,
coverage_output=coverage_output,
rlimit_nofile=rlimit_nofile,
)
args_string = '\n'.join(f'{key}={value!r},' for key, value in args.items())
wrapper = f"""{code}
if __name__ == "__main__":
_ansiballz_main(
{args_string}
)
"""
output.write(to_bytes(wrapper))
b_module_data = output.getvalue()
elif module_substyle == 'powershell':
module_metadata = ModuleMetadataV1(serialization_profile='legacy') # DTFIX-FUTURE: support serialization profiles for PowerShell modules
# Powershell/winrm don't actually make use of shebang so we can
# safely set this here. If we let the fallback code handle this
# it can fail in the presence of the UTF8 BOM commonly added by
# Windows text editors
shebang = '#!powershell'
# create the common exec wrapper payload and set that as the module_data
# bytes
b_module_data = ps_manifest._create_powershell_wrapper(
name=remote_module_fqn,
module_data=b_module_data,
module_path=module_path,
module_args=module_args,
environment=environment,
async_timeout=async_timeout,
become_plugin=become_plugin,
substyle=module_substyle,
task_vars=task_vars,
profile=module_metadata.serialization_profile,
)
elif module_substyle == 'jsonargs':
encoder = get_module_encoder('legacy', Direction.CONTROLLER_TO_MODULE)
module_args_json = to_bytes(json.dumps(module_args, cls=encoder))
# these strings could be included in a third-party module but
# officially they were included in the 'basic' snippet for new-style
# python modules (which has been replaced with something else in
# ansiballz) If we remove them from jsonargs-style module replacer
# then we can remove them everywhere.
python_repred_args = to_bytes(repr(module_args_json))
b_module_data = b_module_data.replace(REPLACER_VERSION, to_bytes(repr(__version__)))
b_module_data = b_module_data.replace(REPLACER_COMPLEX, python_repred_args)
b_module_data = b_module_data.replace(
REPLACER_SELINUX,
to_bytes(','.join(C.DEFAULT_SELINUX_SPECIAL_FS))) # type: ignore[attr-defined]
# The main event -- substitute the JSON args string into the module
b_module_data = b_module_data.replace(REPLACER_JSONARGS, module_args_json)
syslog_facility = task_vars.get(
'ansible_syslog_facility',
C.DEFAULT_SYSLOG_FACILITY) # type: ignore[attr-defined]
facility = b'syslog.' + to_bytes(syslog_facility, errors='surrogate_or_strict')
b_module_data = b_module_data.replace(b'syslog.LOG_USER', facility)
module_metadata = ModuleMetadataV1(serialization_profile='legacy')
else:
module_metadata = ModuleMetadataV1(serialization_profile='legacy')
if not isinstance(module_metadata, ModuleMetadataV1):
raise NotImplementedError(type(module_metadata))
return _BuiltModule(
b_module_data=b_module_data,
module_style=module_style,
shebang=shebang,
serialization_profile=module_metadata.serialization_profile,
)
def _extract_interpreter(b_module_data):
"""
Used to extract shebang expression from binary module data and return a text
string with the shebang, or None if no shebang is detected.
"""
interpreter = None
args = []
b_lines = b_module_data.split(b"\n", 1)
if b_lines[0].startswith(b"#!"):
b_shebang = b_lines[0].strip()
# shlex.split needs text on Python 3
cli_split = shlex.split(to_text(b_shebang[2:], errors='surrogate_or_strict'))
# convert args to text
cli_split = [to_text(a, errors='surrogate_or_strict') for a in cli_split]
interpreter = cli_split[0]
args = cli_split[1:]
return interpreter, args
def modify_module(
*,
module_name: str,
module_path,
module_args,
templar,
task_vars=None,
module_compression='ZIP_STORED',
async_timeout=0,
become_plugin=None,
environment=None,
remote_is_local=False,
) -> _BuiltModule:
"""
Used to insert chunks of code into modules before transfer rather than
doing regular python imports. This allows for more efficient transfer in
a non-bootstrapping scenario by not moving extra files over the wire and
also takes care of embedding arguments in the transferred modules.
This version is done in such a way that local imports can still be
used in the module code, so IDEs don't have to be aware of what is going on.
Example:
from ansible.module_utils.basic import *
... will result in the insertion of basic.py into the module
from the module_utils/ directory in the source tree.
For powershell, this code effectively no-ops, as the exec wrapper requires access to a number of
properties not available here.
"""
task_vars = {} if task_vars is None else task_vars
environment = {} if environment is None else environment
with open(module_path, 'rb') as f:
# read in the module source
b_module_data = f.read()
module_bits = _find_module_utils(
module_name=module_name,
b_module_data=b_module_data,
module_path=module_path,
module_args=module_args,
task_vars=task_vars,
templar=templar,
module_compression=module_compression,
async_timeout=async_timeout,
become_plugin=become_plugin,
environment=environment,
remote_is_local=remote_is_local,
)
b_module_data = module_bits.b_module_data
shebang = module_bits.shebang
if module_bits.module_style == 'binary':
return _BuiltModule(
b_module_data=module_bits.b_module_data,
module_style=module_bits.module_style,
shebang=to_text(module_bits.shebang, nonstring='passthru'),
serialization_profile=module_bits.serialization_profile,
)
elif shebang is None:
interpreter, args = _extract_interpreter(b_module_data)
# No interpreter/shebang, assume a binary module?
if interpreter is not None:
shebang, new_interpreter = _get_shebang(interpreter, task_vars, templar, args, remote_is_local=remote_is_local)
# update shebang
b_lines = b_module_data.split(b"\n", 1)
if interpreter != new_interpreter:
b_lines[0] = to_bytes(shebang, errors='surrogate_or_strict', nonstring='passthru')
b_module_data = b"\n".join(b_lines)
return _BuiltModule(
b_module_data=b_module_data,
module_style=module_bits.module_style,
shebang=shebang,
serialization_profile=module_bits.serialization_profile,
)
def _get_action_arg_defaults(action: str, task: Task, templar: TemplateEngine) -> dict[str, t.Any]:
action_groups = task._parent._play._action_groups
defaults = task.module_defaults
# Get the list of groups that contain this action
if action_groups is None:
msg = (
"Finding module_defaults for action %s. "
"The caller has not passed the action_groups, so any "
"that may include this action will be ignored."
)
display.warning(msg=msg)
group_names = []
else:
group_names = action_groups.get(action, [])
tmp_args: dict[str, t.Any] = {}
module_defaults = {}
# Merge latest defaults into dict, since they are a list of dicts
if isinstance(defaults, list):
for default in defaults:
module_defaults.update(default)
for default in module_defaults:
if default.startswith('group/'):
group_name = default.split('group/')[-1]
if group_name in group_names:
tmp_args.update(templar.resolve_to_container(module_defaults.get(f'group/{group_name}', {})))
# handle specific action defaults
tmp_args.update(templar.resolve_to_container(module_defaults.get(action, {})))
return tmp_args
def _apply_action_arg_defaults(action: str, task: Task, action_args: dict[str, t.Any], templar: Templar) -> dict[str, t.Any]:
args = _get_action_arg_defaults(action, task, templar._engine)
args.update(action_args)
return args
ansible_core-2.19.0b4/lib/ansible/executor/play_iterator.py 0000644 0000000 0000000 00000077032 15010426755 022503 0 ustar 00root root # (c) 2012-2014, Michael DeHaan
#
# 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 .
from __future__ import annotations
import fnmatch
from enum import IntEnum, IntFlag
from ansible import constants as C
from ansible.errors import AnsibleAssertionError
from ansible.module_utils.parsing.convert_bool import boolean
from ansible.playbook.block import Block
from ansible.playbook.task import Task
from ansible.utils.display import Display
display = Display()
__all__ = ['PlayIterator', 'IteratingStates', 'FailedStates']
class IteratingStates(IntEnum):
SETUP = 0
TASKS = 1
RESCUE = 2
ALWAYS = 3
HANDLERS = 4
COMPLETE = 5
class FailedStates(IntFlag):
NONE = 0
SETUP = 1
TASKS = 2
RESCUE = 4
ALWAYS = 8
HANDLERS = 16 # NOTE not in use anymore
class HostState:
def __init__(self, blocks):
self._blocks = blocks[:]
self.handlers = []
self.handler_notifications = []
self.cur_block = 0
self.cur_regular_task = 0
self.cur_rescue_task = 0
self.cur_always_task = 0
self.cur_handlers_task = 0
self.run_state = IteratingStates.SETUP
self.fail_state = FailedStates.NONE
self.pre_flushing_run_state = None
self.update_handlers = True
self.pending_setup = False
self.tasks_child_state = None
self.rescue_child_state = None
self.always_child_state = None
self.did_rescue = False
self.did_start_at_task = False
def __repr__(self):
return "HostState(%r)" % self._blocks
def __str__(self):
return ("HOST STATE: block=%d, task=%d, rescue=%d, always=%d, handlers=%d, run_state=%s, fail_state=%s, "
"pre_flushing_run_state=%s, update_handlers=%s, pending_setup=%s, "
"tasks child state? (%s), rescue child state? (%s), always child state? (%s), "
"did rescue? %s, did start at task? %s" % (
self.cur_block,
self.cur_regular_task,
self.cur_rescue_task,
self.cur_always_task,
self.cur_handlers_task,
self.run_state,
self.fail_state,
self.pre_flushing_run_state,
self.update_handlers,
self.pending_setup,
self.tasks_child_state,
self.rescue_child_state,
self.always_child_state,
self.did_rescue,
self.did_start_at_task,
))
def __eq__(self, other):
if not isinstance(other, HostState):
return False
for attr in ('_blocks',
'cur_block', 'cur_regular_task', 'cur_rescue_task', 'cur_always_task', 'cur_handlers_task',
'run_state', 'fail_state', 'pre_flushing_run_state', 'update_handlers', 'pending_setup',
'tasks_child_state', 'rescue_child_state', 'always_child_state'):
if getattr(self, attr) != getattr(other, attr):
return False
return True
def get_current_block(self):
return self._blocks[self.cur_block]
def copy(self):
new_state = HostState(self._blocks)
new_state.handlers = self.handlers[:]
new_state.handler_notifications = self.handler_notifications[:]
new_state.cur_block = self.cur_block
new_state.cur_regular_task = self.cur_regular_task
new_state.cur_rescue_task = self.cur_rescue_task
new_state.cur_always_task = self.cur_always_task
new_state.cur_handlers_task = self.cur_handlers_task
new_state.run_state = self.run_state
new_state.fail_state = self.fail_state
new_state.pre_flushing_run_state = self.pre_flushing_run_state
new_state.update_handlers = self.update_handlers
new_state.pending_setup = self.pending_setup
new_state.did_rescue = self.did_rescue
new_state.did_start_at_task = self.did_start_at_task
if self.tasks_child_state is not None:
new_state.tasks_child_state = self.tasks_child_state.copy()
if self.rescue_child_state is not None:
new_state.rescue_child_state = self.rescue_child_state.copy()
if self.always_child_state is not None:
new_state.always_child_state = self.always_child_state.copy()
return new_state
class PlayIterator:
def __init__(self, inventory, play, play_context, variable_manager, all_vars, start_at_done=False):
self._play = play
self._blocks = []
self._variable_manager = variable_manager
setup_block = Block(play=self._play)
# Gathering facts with run_once would copy the facts from one host to
# the others.
setup_block.run_once = False
setup_task = Task(block=setup_block)
setup_task.action = 'gather_facts'
setup_task.name = 'Gathering Facts'
setup_task.args = {}
# Unless play is specifically tagged, gathering should 'always' run
if not self._play.tags:
setup_task.tags = ['always']
# Default options to gather
for option in ('gather_subset', 'gather_timeout', 'fact_path'):
value = getattr(self._play, option, None)
if value is not None:
setup_task.args[option] = value
setup_task.set_loader(self._play._loader)
# short circuit fact gathering if the entire playbook is conditional
if self._play._included_conditional is not None:
setup_task.when = self._play._included_conditional[:]
setup_block.block = [setup_task]
setup_block = setup_block.filter_tagged_tasks(all_vars)
self._blocks.append(setup_block)
# keep flatten (no blocks) list of all tasks from the play
# used for the lockstep mechanism in the linear strategy
self.all_tasks = setup_block.get_tasks()
for block in self._play.compile():
new_block = block.filter_tagged_tasks(all_vars)
if new_block.has_tasks():
self._blocks.append(new_block)
self.all_tasks.extend(new_block.get_tasks())
# keep list of all handlers, it is copied into each HostState
# at the beginning of IteratingStates.HANDLERS
# the copy happens at each flush in order to restore the original
# list and remove any included handlers that might not be notified
# at the particular flush
self.handlers = [h for b in self._play.handlers for h in b.block]
self._host_states = {}
start_at_matched = False
batch = inventory.get_hosts(self._play.hosts, order=self._play.order)
self.batch_size = len(batch)
for host in batch:
self.set_state_for_host(host.name, HostState(blocks=self._blocks))
# if we're looking to start at a specific task, iterate through
# the tasks for this host until we find the specified task
if play_context.start_at_task is not None and not start_at_done:
while True:
(s, task) = self.get_next_task_for_host(host, peek=True)
if s.run_state == IteratingStates.COMPLETE:
break
if task.name == play_context.start_at_task or (task.name and fnmatch.fnmatch(task.name, play_context.start_at_task)) or \
task.get_name() == play_context.start_at_task or fnmatch.fnmatch(task.get_name(), play_context.start_at_task):
start_at_matched = True
break
self.set_state_for_host(host.name, s)
# finally, reset the host's state to IteratingStates.SETUP
if start_at_matched:
self._host_states[host.name].did_start_at_task = True
self._host_states[host.name].run_state = IteratingStates.SETUP
if start_at_matched:
# we have our match, so clear the start_at_task field on the
# play context to flag that we've started at a task (and future
# plays won't try to advance)
play_context.start_at_task = None
self.end_play = False
self.cur_task = 0
def get_host_state(self, host):
# Since we're using the PlayIterator to carry forward failed hosts,
# in the event that a previous host was not in the current inventory
# we create a stub state for it now
if host.name not in self._host_states:
self.set_state_for_host(host.name, HostState(blocks=[]))
return self._host_states[host.name].copy()
def get_next_task_for_host(self, host, peek=False):
display.debug("getting the next task for host %s" % host.name)
s = self.get_host_state(host)
task = None
if s.run_state == IteratingStates.COMPLETE:
display.debug("host %s is done iterating, returning" % host.name)
return (s, None)
(s, task) = self._get_next_task_from_state(s, host=host)
if not peek:
self.set_state_for_host(host.name, s)
display.debug("done getting next task for host %s" % host.name)
display.debug(" ^ state is: %s" % s)
return (s, task)
def _get_next_task_from_state(self, state, host):
task = None
# try and find the next task, given the current state.
while True:
# try to get the current block from the list of blocks, and
# if we run past the end of the list we know we're done with
# this block
try:
block = state._blocks[state.cur_block]
except IndexError:
state.run_state = IteratingStates.COMPLETE
return (state, None)
if state.run_state == IteratingStates.SETUP:
# First, we check to see if we were pending setup. If not, this is
# the first trip through IteratingStates.SETUP, so we set the pending_setup
# flag and try to determine if we do in fact want to gather facts for
# the specified host.
if not state.pending_setup:
state.pending_setup = True
# Gather facts if the default is 'smart' and we have not yet
# done it for this host; or if 'explicit' and the play sets
# gather_facts to True; or if 'implicit' and the play does
# NOT explicitly set gather_facts to False.
gathering = C.DEFAULT_GATHERING
implied = self._play.gather_facts is None or boolean(self._play.gather_facts, strict=False)
if (gathering == 'implicit' and implied) or \
(gathering == 'explicit' and boolean(self._play.gather_facts, strict=False)) or \
(gathering == 'smart' and implied and not self._variable_manager._facts_gathered_for_host(host.name)):
# The setup block is always self._blocks[0], as we inject it
# during the play compilation in __init__ above.
setup_block = self._blocks[0]
if setup_block.has_tasks() and len(setup_block.block) > 0:
task = setup_block.block[0]
else:
# This is the second trip through IteratingStates.SETUP, so we clear
# the flag and move onto the next block in the list while setting
# the run state to IteratingStates.TASKS
state.pending_setup = False
state.run_state = IteratingStates.TASKS
if not state.did_start_at_task:
state.cur_block += 1
state.cur_regular_task = 0
state.cur_rescue_task = 0
state.cur_always_task = 0
state.tasks_child_state = None
state.rescue_child_state = None
state.always_child_state = None
elif state.run_state == IteratingStates.TASKS:
# clear the pending setup flag, since we're past that and it didn't fail
if state.pending_setup:
state.pending_setup = False
# First, we check for a child task state that is not failed, and if we
# have one recurse into it for the next task. If we're done with the child
# state, we clear it and drop back to getting the next task from the list.
if state.tasks_child_state:
(state.tasks_child_state, task) = self._get_next_task_from_state(state.tasks_child_state, host=host)
if self._check_failed_state(state.tasks_child_state):
# failed child state, so clear it and move into the rescue portion
state.tasks_child_state = None
self._set_failed_state(state)
else:
# get the next task recursively
if task is None or state.tasks_child_state.run_state == IteratingStates.COMPLETE:
# we're done with the child state, so clear it and continue
# back to the top of the loop to get the next task
state.tasks_child_state = None
continue
else:
# First here, we check to see if we've failed anywhere down the chain
# of states we have, and if so we move onto the rescue portion. Otherwise,
# we check to see if we've moved past the end of the list of tasks. If so,
# we move into the always portion of the block, otherwise we get the next
# task from the list.
if self._check_failed_state(state):
state.run_state = IteratingStates.RESCUE
elif state.cur_regular_task >= len(block.block):
state.run_state = IteratingStates.ALWAYS
else:
task = block.block[state.cur_regular_task]
# if the current task is actually a child block, create a child
# state for us to recurse into on the next pass
if isinstance(task, Block):
state.tasks_child_state = HostState(blocks=[task])
state.tasks_child_state.run_state = IteratingStates.TASKS
# since we've created the child state, clear the task
# so we can pick up the child state on the next pass
task = None
state.cur_regular_task += 1
elif state.run_state == IteratingStates.RESCUE:
# The process here is identical to IteratingStates.TASKS, except instead
# we move into the always portion of the block.
if state.rescue_child_state:
(state.rescue_child_state, task) = self._get_next_task_from_state(state.rescue_child_state, host=host)
if self._check_failed_state(state.rescue_child_state):
state.rescue_child_state = None
self._set_failed_state(state)
else:
if task is None or state.rescue_child_state.run_state == IteratingStates.COMPLETE:
state.rescue_child_state = None
continue
else:
if state.fail_state & FailedStates.RESCUE == FailedStates.RESCUE:
state.run_state = IteratingStates.ALWAYS
elif state.cur_rescue_task >= len(block.rescue):
if len(block.rescue) > 0:
state.fail_state = FailedStates.NONE
state.run_state = IteratingStates.ALWAYS
state.did_rescue = True
else:
task = block.rescue[state.cur_rescue_task]
if isinstance(task, Block):
state.rescue_child_state = HostState(blocks=[task])
state.rescue_child_state.run_state = IteratingStates.TASKS
task = None
state.cur_rescue_task += 1
elif state.run_state == IteratingStates.ALWAYS:
# And again, the process here is identical to IteratingStates.TASKS, except
# instead we either move onto the next block in the list, or we set the
# run state to IteratingStates.COMPLETE in the event of any errors, or when we
# have hit the end of the list of blocks.
if state.always_child_state:
(state.always_child_state, task) = self._get_next_task_from_state(state.always_child_state, host=host)
if self._check_failed_state(state.always_child_state):
state.always_child_state = None
self._set_failed_state(state)
else:
if task is None or state.always_child_state.run_state == IteratingStates.COMPLETE:
state.always_child_state = None
continue
else:
if state.cur_always_task >= len(block.always):
if state.fail_state != FailedStates.NONE:
state.run_state = IteratingStates.COMPLETE
else:
state.cur_block += 1
state.cur_regular_task = 0
state.cur_rescue_task = 0
state.cur_always_task = 0
state.run_state = IteratingStates.TASKS
state.tasks_child_state = None
state.rescue_child_state = None
state.always_child_state = None
state.did_rescue = False
else:
task = block.always[state.cur_always_task]
if isinstance(task, Block):
state.always_child_state = HostState(blocks=[task])
state.always_child_state.run_state = IteratingStates.TASKS
task = None
state.cur_always_task += 1
elif state.run_state == IteratingStates.HANDLERS:
if state.update_handlers:
# reset handlers for HostState since handlers from include_tasks
# might be there from previous flush
state.handlers = self.handlers[:]
state.update_handlers = False
while True:
try:
task = state.handlers[state.cur_handlers_task]
except IndexError:
task = None
state.cur_handlers_task = 0
state.run_state = state.pre_flushing_run_state
state.update_handlers = True
break
else:
state.cur_handlers_task += 1
if task.is_host_notified(host):
return state, task
elif state.run_state == IteratingStates.COMPLETE:
return (state, None)
# if something above set the task, break out of the loop now
if task:
# skip implicit flush_handlers if there are no handlers notified
if (
task.implicit
and task._get_meta() == 'flush_handlers'
and (
# the state store in the `state` variable could be a nested state,
# notifications are always stored in the top level state, get it here
not self.get_state_for_host(host.name).handler_notifications
# in case handlers notifying other handlers, the notifications are not
# saved in `handler_notifications` and handlers are notified directly
# to prevent duplicate handler runs, so check whether any handler
# is notified
and all(not h.notified_hosts for h in self.handlers)
)
):
display.debug("No handler notifications for %s, skipping." % host.name)
elif (
(role := task._role)
and role._metadata.allow_duplicates is False
and host.name in self._play._get_cached_role(role)._completed
):
display.debug("'%s' skipped because role has already run" % task)
else:
break
return (state, task)
def _set_failed_state(self, state):
if state.run_state == IteratingStates.SETUP:
state.fail_state |= FailedStates.SETUP
state.run_state = IteratingStates.COMPLETE
elif state.run_state == IteratingStates.TASKS:
if state.tasks_child_state is not None:
state.tasks_child_state = self._set_failed_state(state.tasks_child_state)
else:
state.fail_state |= FailedStates.TASKS
if state._blocks[state.cur_block].rescue:
state.run_state = IteratingStates.RESCUE
elif state._blocks[state.cur_block].always:
state.run_state = IteratingStates.ALWAYS
else:
state.run_state = IteratingStates.COMPLETE
elif state.run_state == IteratingStates.RESCUE:
if state.rescue_child_state is not None:
state.rescue_child_state = self._set_failed_state(state.rescue_child_state)
else:
state.fail_state |= FailedStates.RESCUE
if state._blocks[state.cur_block].always:
state.run_state = IteratingStates.ALWAYS
else:
state.run_state = IteratingStates.COMPLETE
elif state.run_state == IteratingStates.ALWAYS:
if state.always_child_state is not None:
state.always_child_state = self._set_failed_state(state.always_child_state)
else:
state.fail_state |= FailedStates.ALWAYS
state.run_state = IteratingStates.COMPLETE
return state
def mark_host_failed(self, host):
s = self.get_host_state(host)
display.debug("marking host %s failed, current state: %s" % (host, s))
if s.run_state == IteratingStates.HANDLERS:
# we are failing `meta: flush_handlers`, so just reset the state to whatever
# it was before and let `_set_failed_state` figure out the next state
s.run_state = s.pre_flushing_run_state
s.update_handlers = True
s = self._set_failed_state(s)
display.debug("^ failed state is now: %s" % s)
self.set_state_for_host(host.name, s)
self._play._removed_hosts.append(host.name)
def get_failed_hosts(self):
return dict((host, True) for (host, state) in self._host_states.items() if self._check_failed_state(state))
def _check_failed_state(self, state):
if state is None:
return False
elif state.run_state == IteratingStates.RESCUE and self._check_failed_state(state.rescue_child_state):
return True
elif state.run_state == IteratingStates.ALWAYS and self._check_failed_state(state.always_child_state):
return True
elif state.fail_state != FailedStates.NONE:
if state.run_state == IteratingStates.RESCUE and state.fail_state & FailedStates.RESCUE == 0:
return False
elif state.run_state == IteratingStates.ALWAYS and state.fail_state & FailedStates.ALWAYS == 0:
return False
else:
return not (state.did_rescue and state.fail_state & FailedStates.ALWAYS == 0)
elif state.run_state == IteratingStates.TASKS and self._check_failed_state(state.tasks_child_state):
cur_block = state._blocks[state.cur_block]
if len(cur_block.rescue) > 0 and state.fail_state & FailedStates.RESCUE == 0:
return False
else:
return True
return False
def is_failed(self, host):
s = self.get_host_state(host)
return self._check_failed_state(s)
def clear_host_errors(self, host):
self._clear_state_errors(self.get_state_for_host(host.name))
def _clear_state_errors(self, state: HostState) -> None:
state.fail_state = FailedStates.NONE
if state.tasks_child_state is not None:
self._clear_state_errors(state.tasks_child_state)
elif state.rescue_child_state is not None:
self._clear_state_errors(state.rescue_child_state)
elif state.always_child_state is not None:
self._clear_state_errors(state.always_child_state)
def get_active_state(self, state):
"""
Finds the active state, recursively if necessary when there are child states.
"""
if state.run_state == IteratingStates.TASKS and state.tasks_child_state is not None:
return self.get_active_state(state.tasks_child_state)
elif state.run_state == IteratingStates.RESCUE and state.rescue_child_state is not None:
return self.get_active_state(state.rescue_child_state)
elif state.run_state == IteratingStates.ALWAYS and state.always_child_state is not None:
return self.get_active_state(state.always_child_state)
return state
def is_any_block_rescuing(self, state):
"""
Given the current HostState state, determines if the current block, or any child blocks,
are in rescue mode.
"""
if state.run_state == IteratingStates.TASKS and state.get_current_block().rescue:
return True
if state.tasks_child_state is not None:
return self.is_any_block_rescuing(state.tasks_child_state)
if state.rescue_child_state is not None:
return self.is_any_block_rescuing(state.rescue_child_state)
if state.always_child_state is not None:
return self.is_any_block_rescuing(state.always_child_state)
return False
def _insert_tasks_into_state(self, state, task_list):
# if we've failed at all, or if the task list is empty, just return the current state
if (state.fail_state != FailedStates.NONE and state.run_state == IteratingStates.TASKS) or not task_list:
return state
if state.run_state == IteratingStates.TASKS:
if state.tasks_child_state:
state.tasks_child_state = self._insert_tasks_into_state(state.tasks_child_state, task_list)
else:
target_block = state._blocks[state.cur_block].copy(exclude_tasks=True)
target_block.block[state.cur_regular_task:state.cur_regular_task] = task_list
state._blocks[state.cur_block] = target_block
elif state.run_state == IteratingStates.RESCUE:
if state.rescue_child_state:
state.rescue_child_state = self._insert_tasks_into_state(state.rescue_child_state, task_list)
else:
target_block = state._blocks[state.cur_block].copy(exclude_tasks=True)
target_block.rescue[state.cur_rescue_task:state.cur_rescue_task] = task_list
state._blocks[state.cur_block] = target_block
elif state.run_state == IteratingStates.ALWAYS:
if state.always_child_state:
state.always_child_state = self._insert_tasks_into_state(state.always_child_state, task_list)
else:
target_block = state._blocks[state.cur_block].copy(exclude_tasks=True)
target_block.always[state.cur_always_task:state.cur_always_task] = task_list
state._blocks[state.cur_block] = target_block
elif state.run_state == IteratingStates.HANDLERS:
state.handlers[state.cur_handlers_task:state.cur_handlers_task] = [h for b in task_list for h in b.block]
return state
def add_tasks(self, host, task_list):
self.set_state_for_host(host.name, self._insert_tasks_into_state(self.get_host_state(host), task_list))
@property
def host_states(self):
return self._host_states
def get_state_for_host(self, hostname: str) -> HostState:
return self._host_states[hostname]
def set_state_for_host(self, hostname: str, state: HostState) -> None:
if not isinstance(state, HostState):
raise AnsibleAssertionError('Expected state to be a HostState but was a %s' % type(state))
self._host_states[hostname] = state
def set_run_state_for_host(self, hostname: str, run_state: IteratingStates) -> None:
if not isinstance(run_state, IteratingStates):
raise AnsibleAssertionError('Expected run_state to be a IteratingStates but was %s' % (type(run_state)))
self._host_states[hostname].run_state = run_state
def set_fail_state_for_host(self, hostname: str, fail_state: FailedStates) -> None:
if not isinstance(fail_state, FailedStates):
raise AnsibleAssertionError('Expected fail_state to be a FailedStates but was %s' % (type(fail_state)))
self._host_states[hostname].fail_state = fail_state
def add_notification(self, hostname: str, notification: str) -> None:
# preserve order
host_state = self._host_states[hostname]
if notification not in host_state.handler_notifications:
host_state.handler_notifications.append(notification)
def clear_notification(self, hostname: str, notification: str) -> None:
self._host_states[hostname].handler_notifications.remove(notification)
def end_host(self, hostname: str) -> None:
"""Used by ``end_host``, ``end_batch`` and ``end_play`` meta tasks to end executing given host."""
state = self.get_active_state(self.get_state_for_host(hostname))
if state.run_state == IteratingStates.RESCUE:
# This is a special case for when ending a host occurs in rescue.
# By definition the meta task responsible for ending the host
# is the last task, so we need to clear the fail state to mark
# the host as rescued.
# The reason we need to do that is because this operation is
# normally done when PlayIterator transitions from rescue to
# always when only then we can say that rescue didn't fail
# but with ending a host via meta task, we don't get to that transition.
self.set_fail_state_for_host(hostname, FailedStates.NONE)
self.set_run_state_for_host(hostname, IteratingStates.COMPLETE)
self._play._removed_hosts.append(hostname)
ansible_core-2.19.0b4/lib/ansible/executor/playbook_executor.py 0000644 0000000 0000000 00000034726 15010426755 023366 0 ustar 00root root # (c) 2012-2014, Michael DeHaan
#
# 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 .
from __future__ import annotations
import os
from ansible import constants as C
from ansible import context
from ansible.executor.task_queue_manager import TaskQueueManager, AnsibleEndPlay
from ansible.module_utils.common.text.converters import to_text
from ansible.module_utils.parsing.convert_bool import boolean
from ansible.plugins.loader import become_loader, connection_loader, shell_loader
from ansible.playbook import Playbook
from ansible._internal._templating._engine import TemplateEngine
from ansible.utils.helpers import pct_to_int
from ansible.utils.collection_loader import AnsibleCollectionConfig
from ansible.utils.collection_loader._collection_finder import _get_collection_name_from_path, _get_collection_playbook_path
from ansible.utils.path import makedirs_safe
from ansible.utils.ssh_functions import set_default_transport
from ansible.utils.display import Display
display = Display()
class PlaybookExecutor:
"""
This is the primary class for executing playbooks, and thus the
basis for bin/ansible-playbook operation.
"""
def __init__(self, playbooks, inventory, variable_manager, loader, passwords):
self._playbooks = playbooks
self._inventory = inventory
self._variable_manager = variable_manager
self._loader = loader
self.passwords = passwords
self._unreachable_hosts = dict()
if context.CLIARGS.get('listhosts') or context.CLIARGS.get('listtasks') or \
context.CLIARGS.get('listtags') or context.CLIARGS.get('syntax'):
self._tqm = None
else:
self._tqm = TaskQueueManager(
inventory=inventory,
variable_manager=variable_manager,
loader=loader,
passwords=self.passwords,
forks=context.CLIARGS.get('forks'),
)
# Note: We run this here to cache whether the default ansible ssh
# executable supports control persist. Sometime in the future we may
# need to enhance this to check that ansible_ssh_executable specified
# in inventory is also cached. We can't do this caching at the point
# where it is used (in task_executor) because that is post-fork and
# therefore would be discarded after every task.
set_default_transport()
def run(self):
"""
Run the given playbook, based on the settings in the play which
may limit the runs to serialized groups, etc.
"""
result = 0
entrylist = []
entry = {}
try:
# preload become/connection/shell to set config defs cached
list(connection_loader.all(class_only=True))
list(shell_loader.all(class_only=True))
list(become_loader.all(class_only=True))
for playbook in self._playbooks:
# deal with FQCN
resource = _get_collection_playbook_path(playbook)
if resource is not None:
playbook_path = resource[1]
playbook_collection = resource[2]
else:
playbook_path = playbook
# not fqcn, but might still be collection playbook
playbook_collection = _get_collection_name_from_path(playbook)
if playbook_collection:
display.v("running playbook inside collection {0}".format(playbook_collection))
AnsibleCollectionConfig.default_collection = playbook_collection
else:
AnsibleCollectionConfig.default_collection = None
pb = Playbook.load(playbook_path, variable_manager=self._variable_manager, loader=self._loader)
# FIXME: move out of inventory self._inventory.set_playbook_basedir(os.path.realpath(os.path.dirname(playbook_path)))
if self._tqm is None: # we are doing a listing
entry = {'playbook': playbook_path}
entry['plays'] = []
else:
# make sure the tqm has callbacks loaded
self._tqm.load_callbacks()
self._tqm.send_callback('v2_playbook_on_start', pb)
i = 1
plays = pb.get_plays()
display.vv(u'%d plays in %s' % (len(plays), to_text(playbook_path)))
for play in plays:
if play._included_path is not None:
self._loader.set_basedir(play._included_path)
else:
self._loader.set_basedir(pb._basedir)
# clear any filters which may have been applied to the inventory
self._inventory.remove_restriction()
# Allow variables to be used in vars_prompt fields.
all_vars = self._variable_manager.get_vars(play=play)
templar = TemplateEngine(loader=self._loader, variables=all_vars)
setattr(play, 'vars_prompt', templar.template(play.vars_prompt))
# FIXME: this should be a play 'sub object' like loop_control
if play.vars_prompt:
for var in play.vars_prompt:
vname = var['name']
prompt = var.get("prompt", vname)
default = var.get("default", None)
private = boolean(var.get("private", True))
confirm = boolean(var.get("confirm", False))
encrypt = var.get("encrypt", None)
salt_size = var.get("salt_size", None)
salt = var.get("salt", None)
unsafe = boolean(var.get("unsafe", False))
if vname not in self._variable_manager.extra_vars:
if self._tqm:
self._tqm.send_callback('v2_playbook_on_vars_prompt', vname, private, prompt, encrypt, confirm, salt_size, salt,
default, unsafe)
play.vars[vname] = display.do_var_prompt(vname, private, prompt, encrypt, confirm, salt_size, salt, default, unsafe)
else: # we are either in --list-