Compare commits
107 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| cd9d6f0958 | |||
| a9b4313570 | |||
| 387093a0d6 | |||
| 72af010414 | |||
| 543bfbbe7f | |||
| 5a6b926744 | |||
| 457efa8136 | |||
| e925dd7713 | |||
| 0829325d21 | |||
| f084305466 | |||
| fba466a26f | |||
| 22d7b7e5f2 | |||
| f03d9c1450 | |||
| fdbb83cea0 | |||
| 17f90a68cc | |||
| f5de633197 | |||
| 196018952b | |||
| 57935b76d7 | |||
| 630e8cb8e2 | |||
| 104f39a41d | |||
| ebaf42bbbe | |||
| 5c3c3fc835 | |||
| e0a3c6214d | |||
| 74e90f89bd | |||
| f64e95f230 | |||
| 76f6d21ff3 | |||
| 0cfbc1feb8 | |||
| 9fd0254954 | |||
| 942d38ae24 | |||
| 99d3a641eb | |||
| 118f008c59 | |||
| 14531144cf | |||
| d5cd383855 | |||
| 4cd7c2987f | |||
| 3044b855b4 | |||
| 8b88eecde3 | |||
| 7c678aaff8 | |||
| ebe89926f0 | |||
| d73da98ecf | |||
| 6d8b124e16 | |||
| ebd7820a44 | |||
| a87b36219b | |||
| cec67624ba | |||
| 4dee11336c | |||
| 3cd3c0d7c6 | |||
| 905b9b162d | |||
| 2e4c1dc3cb | |||
| 2e80441948 | |||
| 368375810b | |||
| d83e722b82 | |||
| d83adc4deb | |||
| c4d98fa134 | |||
| 49c52a89ea | |||
| a851a0db08 | |||
| 564393a5e0 | |||
| 80e4fc47c3 | |||
| 91afa0483f | |||
| 33ca2d192f | |||
| f5561c65bc | |||
| e64ea2a0b1 | |||
| 36225e1603 | |||
| 9562217680 | |||
| 980e5cbdb4 | |||
| 65035e2149 | |||
| 30906ff632 | |||
| 1463fdd02a | |||
| 57d3a17965 | |||
| 2781230d8e | |||
| 1856babfa5 | |||
| 77d5fa20d8 | |||
| 91bf8402d1 | |||
| 1f84c4982f | |||
| 2a118b4cbd | |||
| 4378d8becf | |||
| 0131ad25bf | |||
| 93758a5141 | |||
| 45ff67b744 | |||
| a5a54455a4 | |||
| 8e801d5394 | |||
| 5af5e70f6b | |||
| 33824f313e | |||
| c624eb994f | |||
| 424f385548 | |||
| 28348602f8 | |||
| ffa7eaa7a7 | |||
| 8448967c74 | |||
| e62f75192d | |||
| fc37aed6d9 | |||
| c975c0e69b | |||
| e4d9a5185d | |||
| 9cdc204139 | |||
| 9e60b212dd | |||
| ebc717c337 | |||
| 455aa542d0 | |||
| 3117495d43 | |||
| 1f7bb82810 | |||
| ad918699d2 | |||
| 89c3ebf053 | |||
| 3ac5ccda03 | |||
| 5b1645aca9 | |||
| bba6ca4db1 | |||
| 9bc5f72c13 | |||
| 6179a94d9b | |||
| 1a96098bb3 | |||
| bca7f1fe22 | |||
| 65b461b8fe | |||
| 2c4b934482 |
@ -572,7 +572,6 @@ releases:
|
||||
- win_copy-empty-dir.yaml
|
||||
- win_copy-paths.yaml
|
||||
- win_domain-cred.yaml
|
||||
- win_domain_membership-replace.yaml
|
||||
- win_dsc-validation.yaml
|
||||
- win_dsc-warning.yaml
|
||||
- win_file-hidden.yaml
|
||||
@ -1409,3 +1408,125 @@ releases:
|
||||
shell:
|
||||
- cmd
|
||||
release_date: '2019-04-04'
|
||||
2.8.0b1:
|
||||
codename: How Many More Times
|
||||
fragments:
|
||||
- 40366-modify-existing-volume.yml
|
||||
- 45355-mysql_user-fix-versions-compatibilities.yml
|
||||
- 49039-facts-xen-paravirt-cpuinfo.yaml
|
||||
- 54494-ec2-user-data.yaml
|
||||
- 54517-include-partition-table-postgresql-privs.yaml
|
||||
- 54633-openssl_pkcs12_idempotency_fixes.yaml
|
||||
- 54690-openssl_certificate-assertonly.yml
|
||||
- 54692-ec2_asg_fix_reading_properties.yml
|
||||
- 54799-ufw-default-direction.yml
|
||||
- 54974-rename-safeconfigparser-to-configparser.yaml
|
||||
- 55006-setup-is_chroot-btrfs.yaml
|
||||
- 55038-rename-results-key-vmware-guest.yml
|
||||
- 55083-univention-diff-UnboundLocalError.yaml
|
||||
- dnf-4.2.2-module-remove.yaml
|
||||
- facts-pkg-mgr-rhel.yaml
|
||||
- fibre_channel_wwn_fact_aix.yaml
|
||||
- fix_cache_assumption.yml
|
||||
- gcp-compute-add-image.yaml
|
||||
- include-no-swallow-error.yaml
|
||||
- jinja2_nested_undefined_getitem.yaml
|
||||
- paramiko-optional.yaml
|
||||
- redhat_subscription_use_strings_for_yum_plugin_configs.yaml
|
||||
- tower_job_launch-options.yaml
|
||||
- use-module_utils-six-in-contrib-inventory.yaml
|
||||
- user-read-passwd-when-local.yaml
|
||||
- v2.8.0b1_summary.yaml
|
||||
- yum-select-version.yml
|
||||
modules:
|
||||
- azure_rm_devtestlabcustomimage_facts
|
||||
- azure_rm_devtestlabenvironment_facts
|
||||
- azure_rm_devtestlabpolicy_facts
|
||||
- azure_rm_devtestlabschedule_facts
|
||||
- azure_rm_hdinsightcluster_facts
|
||||
- azure_rm_virtualnetworkgateway
|
||||
- cloudscale_server_group
|
||||
- docker_swarm_service_info
|
||||
- keycloak_group
|
||||
- oci_vcn
|
||||
- onyx_buffer_pool
|
||||
- onyx_vxlan
|
||||
- openssl_certificate_info
|
||||
- openssl_csr_info
|
||||
- openssl_privatekey_info
|
||||
- ovirt_role
|
||||
- podman_image
|
||||
- podman_image_info
|
||||
- postgresql_owner
|
||||
- postgresql_slot
|
||||
- vexata_volume
|
||||
- win_format
|
||||
- win_http_proxy
|
||||
- win_inet_proxy
|
||||
- xfs_quota
|
||||
plugins:
|
||||
connection:
|
||||
- vmware_tools
|
||||
inventory:
|
||||
- cloudscale
|
||||
- kubevirt
|
||||
release_date: '2019-04-15'
|
||||
2.8.0rc1:
|
||||
codename: How Many More Times
|
||||
fragments:
|
||||
- 49904-rds_instance-datatype.yml
|
||||
- 54955-docker_container-log_options-strings.yml
|
||||
- 55078-redfish_utils_fix_406_not_acceptable_issue_with_some_oob_controllers.yml
|
||||
- 55142-openssl_csr-crypto-backend-san.yml
|
||||
- 55203-fix-for-removing-subscription-id-from-facts.yaml
|
||||
- 55258-docker_host_info-old-docker-py.yml
|
||||
- 55258-docker_swarm_service_info-old-docker-py.yml
|
||||
- 55266-purefa_facts_remove_line.yaml
|
||||
- 55278-cryto-use-bundled-ipaddress.yml
|
||||
- 55384-netconf-import.yaml
|
||||
- 55546-fixed-replacing-lb-with-ag-in-vmss.yaml
|
||||
- 55591-docker_swarm_service-fix-uid-gid-secrets-config-type.yaml
|
||||
- 55619-vultr_server_idempotency.yml
|
||||
- 55681-azure_rm_manageddisk.yaml
|
||||
- 55688-azure_rm_resourcegroup.yml
|
||||
- 55693-fixing-final-function-app-properties.yml
|
||||
- allow_inv_plugin_loading.yml
|
||||
- ensure_discovery_unsafe.yml
|
||||
- ensure_facts_safe.yml
|
||||
- gitlab-deprecated-version.yaml
|
||||
- k8s-fix_wait_for_response.yaml
|
||||
- meraki_content_filtering-redundant-calls.yml
|
||||
- meraki_static_route_api_calls.yml
|
||||
- meraki_vlan_api_calls.yml
|
||||
- persistent_loading.yml
|
||||
- postgresql_idx-remove-useless-lines.yml
|
||||
- postgresql_slot-fix-sslrootcert.yml
|
||||
- psrp-fetch.yaml
|
||||
- psrp-output.yaml
|
||||
- tower_job_wait-wrong_examples.yml
|
||||
- user-aix-shadow-file-parsing.yaml
|
||||
- v2.8.0rc1_summary.yaml
|
||||
- vmware_portgroup_list_host.yml
|
||||
- vmware_tools_fix_urllib3_import.yaml
|
||||
- vsphere_guest-corrected-state-operations.yml
|
||||
- win_domain-setup.yaml
|
||||
- win_reboot-psrp-command.yaml
|
||||
- win_region-format.yaml
|
||||
release_date: '2019-04-25'
|
||||
2.8.0rc2:
|
||||
codename: How Many More Times
|
||||
fragments:
|
||||
- 55515-use-active-state-for-any_errors_fatal.yaml
|
||||
- bad_empty_play.yml
|
||||
- ps-basic-json.yaml
|
||||
- v2.8.0rc2_summary.yaml
|
||||
release_date: '2019-05-01'
|
||||
2.8.0rc3:
|
||||
codename: How Many More Times
|
||||
fragments:
|
||||
- 51825-vmware_deploy_ovf-add_folder_doc.yml
|
||||
- 56145-ios-net_get-net_put-update.yaml
|
||||
- networkos_config_src_option_fix.yaml
|
||||
- v2.8.0rc3_summary.yaml
|
||||
- vmware_check_ssl_cert.yaml
|
||||
release_date: '2019-05-10'
|
||||
|
||||
@ -5,6 +5,261 @@ Ansible 2.8 "How Many More Times" Release Notes
|
||||
.. contents:: Topics
|
||||
|
||||
|
||||
v2.8.0rc3
|
||||
=========
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
| Release Date: 2019-05-10
|
||||
| `Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`__
|
||||
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Added documentation about the folder parameter with examples in vmware_deploy_ovf (https://github.com/ansible/ansible/issues/51825).
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Fix invalid src option return response for network config modules (https://github.com/ansible/ansible/pull/56076)
|
||||
- Fix net_get and net_put task run failure - https://github.com/ansible/ansible/pull/56145
|
||||
- vmware - The VMware modules now enable the SSL certificate check unless ``validate_certs`` is ``false``.
|
||||
|
||||
v2.8.0rc2
|
||||
=========
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
| Release Date: 2019-05-01
|
||||
| `Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`__
|
||||
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Ansible.Basic - Fix issue when deserilizing a JSON string that is not a dictionary - https://github.com/ansible/ansible/pull/55691
|
||||
- Be sure to use the active state when checking for any_errors_fatal
|
||||
- re allow empty plays for now, but add deprecation msg.
|
||||
|
||||
v2.8.0rc1
|
||||
=========
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
| Release Date: 2019-04-25
|
||||
| `Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`__
|
||||
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- Add variable type for performance_insights_retention_period (https://github.com/ansible/ansible/issues/49904).
|
||||
- Fix API call to _wait_for_response in k8s modules (https://github.com/ansible/ansible/pull/53937).
|
||||
- Try to use bundled urllib3 first, then falls back to non-bundled version in vmware_tools (https://github.com/ansible/ansible/pull/55187).
|
||||
- vmware_portgroup accepts list of ESXi hostsystem. Modified get_all_host_objs API to accept list of hostsystems.
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Enable azure manged disk test
|
||||
- Fixes an issue when subscription_id is masked in the output when it's passed as one of the parameters.
|
||||
- Fixes replacing load balancer with application gateway in Azure virtualmachine scaleset, as leaning up old load balancer was not done properly.
|
||||
- Move netconf import errors from import to use.
|
||||
- SECURITY Fixed the python interpreter detection, added in 2.8.0alpha1, to properly mark the returned data as untemplatable. This prevents a malicious managed machine from running code on the controller via templating.
|
||||
- acme_certificate - use ``ipaddress`` module bundled with Ansible for normalizations needed for OpenSSL backend.
|
||||
- add resource group test
|
||||
- allow loading inventory plugins adjacent to playbooks
|
||||
- azure_rm_functionapp - adding two properties which need to be set by default, otherwise function app won't behave correctly in Azure Portal.
|
||||
- docker_container - fix idempotency of ``log_options`` when non-string values are used. Also warn user that this is the case.
|
||||
- docker_host_info - ``network_filters`` needs docker-py 2.0.2, ``disk_usage`` needs docker-py 2.2.0.
|
||||
- docker_swarm_service - Change the type of options ``gid`` and ``uid`` on ``secrets`` and ``configs`` to ``str``.
|
||||
- docker_swarm_service_info - work around problems with older docker-py versions such as 2.0.2.
|
||||
- ensure module results and facts are marked untrusted as templates for safer use within the same task
|
||||
- gitlab modules - Update version deprecations to use strings instead of integers so that ``2.10`` isn't converted to ``2.1``. (https://github.com/ansible/ansible/pull/55395)
|
||||
- meraki_static_route - Module would make unnecessary API calls to Meraki when ``net_id`` is specified in task.
|
||||
- meraki_static_route - Module would make unnecessary API calls to Meraki when ``net_id`` is specified in task.
|
||||
- meraki_vlan - Module would make unnecessary API calls to Meraki when net_id is specified in task.
|
||||
- openssl_csr - SAN normalization for IP addresses for the pyOpenSSL backend was broken.
|
||||
- openssl_csr - the cryptography backend's idempotency checking for basic constraints was broken.
|
||||
- openssl_csr, openssl_csr_info - use ``ipaddress`` module bundled with Ansible for normalizations needed for pyOpenSSL backend.
|
||||
- pass correct loading context to persistent connections
|
||||
- postgresql_idx - removed useless rows that remained after the previous refactoring
|
||||
- postgresql_slot - fixed sslrootcert mapping to psycopg2 connection string
|
||||
- psrp - Fix blank newlines appearing before ``stdout`` when using ``script`` or ``raw`` with the ``psrp`` connection plugin
|
||||
- psrp - Fix issues when fetching large files causing a memory leak - https://github.com/ansible/ansible/issues/55239
|
||||
- psrp - Fix issues with propagating errors back to Ansible with ``raw`` tasks
|
||||
- purefa_facts - remove unnecessary line that could cause failure in rare circumstances.
|
||||
- redfish_utils - fix "406 Not Acceptable" issue with some OOB controllers (https://github.com/ansible/ansible/issues/55078)
|
||||
- tower_job_wait - Fixed wrong variable specification in examples
|
||||
- user - properly parse the shadow file on AIX (https://github.com/ansible/ansible/issues/54461)
|
||||
- vsphere_guest - creating machines without vm_extra_config allowed
|
||||
- vsphere_guest - powering on/off absent virtual machine will fail
|
||||
- vultr_server - Fix idempotency for options ``ipv6_enabled`` and ``private_network_enabled``.
|
||||
- win_domain - Fix checking for a domain introduced in a recent patch
|
||||
- win_reboot - pass return value for ``test_command`` result when using the ``psrp`` connection plugin
|
||||
- win_region - Fix the check for ``format`` when running on the ``psrp`` connection plugin
|
||||
|
||||
v2.8.0b1
|
||||
========
|
||||
|
||||
Release Summary
|
||||
---------------
|
||||
|
||||
| Release Date: 2019-04-15
|
||||
| `Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`__
|
||||
|
||||
|
||||
Minor Changes
|
||||
-------------
|
||||
|
||||
- add support for extending volumes in os_volume, also add module support for check_mode and diff
|
||||
- ansible facts properly detect xen paravirt vs hvm
|
||||
- gather Fibre Channel WWNs fact on AIX (extends https://github.com/ansible/ansible/pull/37043)
|
||||
- gcp_compute - add the image field to map to disk source iamges in the configured zones bringing it in line with old gce inventory script data
|
||||
- jinja2 - accesses to keys/indices on an undefined value now return further undefined values rather than throwing an exception
|
||||
- openssl_certificate - the messages of the ``assertonly`` provider with respect to private key and CSR checking are now more precise.
|
||||
- openssl_pkcs12 - Fixed idempotency checks, the module will regenerate the pkcs12 file if any of the parameters differ from the ones in the file. The ``ca_certificates`` parameter has been renamed to ``other_certificates``.
|
||||
- paramiko is now optional. There is no compat package on certain platforms to worry about.
|
||||
- rename safeConfigParser to ConfigParser to suppress DeprecationWarning (The SafeConfigParser class has been renamed to ConfigParser in Python 3.2.)
|
||||
- use ansible.module_utils.six for all scripts in contrib/inventory
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
- Fixed to handle arguments correctly even if inventory and credential variables are not specified (#25017,#37567)
|
||||
- Include partition tables in the ALL_IN_SCHEMA option for postgresql-privs (https://github.com/ansible/ansible/issues/54516)
|
||||
- The internal key `results` in vmware_guest_snapshot module return renamed to `snapshot_results`.
|
||||
- dnf - fix issue with dnf API calls to adapt to changes in upstream dnf version 4.2.2
|
||||
- ec2 - Only use user_data if the user has specified a value. This prevents setting the instance's user data to b'None'.
|
||||
- ec2_asg - Fix error where ASG dict has no launch config or launch template key
|
||||
- facts - ensure that the default package manager for RHEL < 8 is yum, and dnf for newer
|
||||
- include_role - Don't swallow errors when processing included files/roles (https://github.com/ansible/ansible/issues/54786)
|
||||
- mysql_user: fix compatibility issues with various MySQL/MariaDB versions
|
||||
- redhat_subscription - For compatibility using the redhat_subscription module on hosts set to use a python 3 interpreter, use string values when updating yum plugin configuration files.
|
||||
- rely on method existing vs loosely related _cache attribute, also fix data persistence issue on plugin reuse across sources.
|
||||
- setup - properly detect is_chroot on Btrfs (https://github.com/ansible/ansible/issues/55006)
|
||||
- udm_dns_record - Fix issues when state is absent with undefined variable diff at the module return.
|
||||
- udm_dns_zone - Fix issues when state is absent with undefined variable diff at the module return.
|
||||
- udm_group - Fix issues when state is absent with undefined variable diff at the module return.
|
||||
- udm_share - Fix issues when state is absent with undefined variable diff at the module return.
|
||||
- udm_user - Fix issues when state is absent with undefined variable diff at the module return.
|
||||
- ufw - when ``default`` is specified, ``direction`` does not needs to be specified. This was accidentally introduced in Ansible 2.7.8.
|
||||
- user - fix a bug when checking if a local user account exists on a system using directory authentication (https://github.com/ansible/ansible/issues/50947, https://github.com/ansible/ansible/issues/38206)
|
||||
- yum allows comparison operators like '>=' for selecting package version
|
||||
|
||||
New Plugins
|
||||
-----------
|
||||
|
||||
Connection
|
||||
~~~~~~~~~~
|
||||
|
||||
- vmware_tools - Execute tasks inside a VM via VMware Tools
|
||||
|
||||
Inventory
|
||||
~~~~~~~~~
|
||||
|
||||
- cloudscale - cloudscale.ch inventory source
|
||||
- kubevirt - KubeVirt inventory source
|
||||
|
||||
New Modules
|
||||
-----------
|
||||
|
||||
Cloud
|
||||
~~~~~
|
||||
|
||||
azure
|
||||
^^^^^
|
||||
|
||||
- azure_rm_devtestlabcustomimage_facts - Get Azure DevTest Lab Custom Image facts.
|
||||
- azure_rm_devtestlabenvironment_facts - Get Azure Environment facts.
|
||||
- azure_rm_devtestlabpolicy_facts - Get Azure DTL Policy facts.
|
||||
- azure_rm_devtestlabschedule_facts - Get Azure Schedule facts.
|
||||
- azure_rm_hdinsightcluster_facts - Get Azure HDInsight Cluster facts.
|
||||
- azure_rm_virtualnetworkgateway - Manage Azure virtual network gateways.
|
||||
|
||||
cloudscale
|
||||
^^^^^^^^^^
|
||||
|
||||
- cloudscale_server_group - Manages server groups on the cloudscale.ch IaaS service
|
||||
|
||||
docker
|
||||
^^^^^^
|
||||
|
||||
- docker_swarm_service_info - Retrieves information about docker services from a Swarm Manager
|
||||
|
||||
oracle
|
||||
^^^^^^
|
||||
|
||||
- oci_vcn - Manage Virtual Cloud Networks(VCN) in OCI
|
||||
|
||||
ovirt
|
||||
^^^^^
|
||||
|
||||
- ovirt_role - Module to manage roles in oVirt/RHV
|
||||
|
||||
podman
|
||||
^^^^^^
|
||||
|
||||
- podman_image - Pull images for use by podman
|
||||
- podman_image_info - Gather info about images using podman
|
||||
|
||||
Crypto
|
||||
~~~~~~
|
||||
|
||||
- openssl_certificate_info - Provide information of OpenSSL X.509 certificates
|
||||
- openssl_csr_info - Provide information of OpenSSL Certificate Signing Requests (CSR)
|
||||
- openssl_privatekey_info - Provide information for OpenSSL private keys
|
||||
|
||||
Database
|
||||
~~~~~~~~
|
||||
|
||||
postgresql
|
||||
^^^^^^^^^^
|
||||
|
||||
- postgresql_owner - Change an owner of PostgreSQL database object
|
||||
- postgresql_slot - Add or remove slots from a PostgreSQL database
|
||||
|
||||
Identity
|
||||
~~~~~~~~
|
||||
|
||||
keycloak
|
||||
^^^^^^^^
|
||||
|
||||
- keycloak_group - Allows administration of Keycloak groups via Keycloak API
|
||||
|
||||
Network
|
||||
~~~~~~~
|
||||
|
||||
onyx
|
||||
^^^^
|
||||
|
||||
- onyx_buffer_pool - Configures Buffer Pool
|
||||
- onyx_vxlan - Configures Vxlan
|
||||
|
||||
Storage
|
||||
~~~~~~~
|
||||
|
||||
vexata
|
||||
^^^^^^
|
||||
|
||||
- vexata_volume - Manage volumes on Vexata VX100 storage arrays
|
||||
|
||||
System
|
||||
~~~~~~
|
||||
|
||||
- xfs_quota - Manage quotas on XFS filesystems
|
||||
|
||||
Windows
|
||||
~~~~~~~
|
||||
|
||||
- win_format - Formats an existing volume or a new volume on an existing partition on Windows
|
||||
- win_http_proxy - Manages proxy settings for WinHTTP
|
||||
- win_inet_proxy - Manages proxy settings for WinINet and Internet Explorer
|
||||
|
||||
v2.8.0a1
|
||||
========
|
||||
|
||||
@ -296,7 +551,6 @@ Expression.
|
||||
- win_chocolatey - Added the ability to pin a package using the ``pinned`` option - https://github.com/ansible/ansible/issues/38526
|
||||
- win_chocolatey - added the allow_multiple module option to allow side by side installs of the same package
|
||||
- win_chocolatey - support bootstrapping Chocolatey from other URLs with any PS script that ends with ``.ps1``, originally this script had to be ``install.ps1``
|
||||
- win_domain_membership - will now fail if an existing AD object for the host exists and ``allow_existing_computer_account=no`` - https://github.com/ansible/ansible/pull/53542
|
||||
- win_dsc - Display the warnings produced by the DSC engine for better troubleshooting - https://github.com/ansible/ansible/issues/51543
|
||||
- win_dsc - The Verbose logs will be returned when running with ``-vvv``.
|
||||
- win_dsc - The module invocation and possible options will be displayed when running with ``-vvv``.
|
||||
@ -1225,7 +1479,7 @@ Net Tools
|
||||
netbox
|
||||
^^^^^^
|
||||
|
||||
- netbox_device - Create or delete devices within Netbox
|
||||
- netbox_device - Create, update or delete devices within Netbox
|
||||
- netbox_interface - Creates or removes interfaces from Netbox
|
||||
- netbox_ip_address - Creates or removes IP addresses from Netbox
|
||||
- netbox_prefix - Creates or removes prefixes from Netbox
|
||||
|
||||
2
changelogs/fragments/49904-rds_instance-datatype.yml
Normal file
2
changelogs/fragments/49904-rds_instance-datatype.yml
Normal file
@ -0,0 +1,2 @@
|
||||
minor_changes:
|
||||
- Add variable type for performance_insights_retention_period (https://github.com/ansible/ansible/issues/49904).
|
||||
@ -0,0 +1,2 @@
|
||||
minor_changes:
|
||||
- Added documentation about the folder parameter with examples in vmware_deploy_ovf (https://github.com/ansible/ansible/issues/51825).
|
||||
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- "docker_container - fix idempotency of ``log_options`` when non-string values are used. Also warn user that this is the case."
|
||||
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- redfish_utils - fix "406 Not Acceptable" issue with some OOB controllers (https://github.com/ansible/ansible/issues/55078)
|
||||
@ -0,0 +1,3 @@
|
||||
bugfixes:
|
||||
- "openssl_csr - the cryptography backend's idempotency checking for basic constraints was broken."
|
||||
- "openssl_csr - SAN normalization for IP addresses for the pyOpenSSL backend was broken."
|
||||
@ -0,0 +1,3 @@
|
||||
---
|
||||
bugfixes:
|
||||
- "Fixes an issue when subscription_id is masked in the output when it's passed as one of the parameters."
|
||||
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- "docker_host_info - ``network_filters`` needs docker-py 2.0.2, ``disk_usage`` needs docker-py 2.2.0."
|
||||
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- "docker_swarm_service_info - work around problems with older docker-py versions such as 2.0.2."
|
||||
2
changelogs/fragments/55266-purefa_facts_remove_line.yaml
Normal file
2
changelogs/fragments/55266-purefa_facts_remove_line.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- "purefa_facts - remove unnecessary line that could cause failure in rare circumstances."
|
||||
@ -0,0 +1,3 @@
|
||||
bugfixes:
|
||||
- "openssl_csr, openssl_csr_info - use ``ipaddress`` module bundled with Ansible for normalizations needed for pyOpenSSL backend."
|
||||
- "acme_certificate - use ``ipaddress`` module bundled with Ansible for normalizations needed for OpenSSL backend."
|
||||
2
changelogs/fragments/55384-netconf-import.yaml
Normal file
2
changelogs/fragments/55384-netconf-import.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- Move netconf import errors from import to use.
|
||||
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- Be sure to use the active state when checking for any_errors_fatal
|
||||
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- Fixes replacing load balancer with application gateway in Azure virtualmachine scaleset, as leaning up old load balancer was not done properly.
|
||||
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- "docker_swarm_service - Change the type of options ``gid`` and ``uid`` on ``secrets`` and ``configs`` to ``str``."
|
||||
2
changelogs/fragments/55619-vultr_server_idempotency.yml
Normal file
2
changelogs/fragments/55619-vultr_server_idempotency.yml
Normal file
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- vultr_server - Fix idempotency for options ``ipv6_enabled`` and ``private_network_enabled``.
|
||||
2
changelogs/fragments/55681-azure_rm_manageddisk.yaml
Normal file
2
changelogs/fragments/55681-azure_rm_manageddisk.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- Enable azure manged disk test
|
||||
2
changelogs/fragments/55688-azure_rm_resourcegroup.yml
Normal file
2
changelogs/fragments/55688-azure_rm_resourcegroup.yml
Normal file
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- add resource group test
|
||||
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- azure_rm_functionapp - adding two properties which need to be set by default, otherwise function app won't behave correctly in Azure Portal.
|
||||
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- Fix net_get and net_put task run failure - https://github.com/ansible/ansible/pull/56145
|
||||
2
changelogs/fragments/allow_inv_plugin_loading.yml
Normal file
2
changelogs/fragments/allow_inv_plugin_loading.yml
Normal file
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- allow loading inventory plugins adjacent to playbooks
|
||||
2
changelogs/fragments/bad_empty_play.yml
Normal file
2
changelogs/fragments/bad_empty_play.yml
Normal file
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- re allow empty plays for now, but add deprecation msg.
|
||||
3
changelogs/fragments/ensure_discovery_unsafe.yml
Normal file
3
changelogs/fragments/ensure_discovery_unsafe.yml
Normal file
@ -0,0 +1,3 @@
|
||||
bugfixes:
|
||||
- SECURITY Fixed the python interpreter detection, added in 2.8.0alpha1, to properly mark the returned data as untemplatable.
|
||||
This prevents a malicious managed machine from running code on the controller via templating.
|
||||
2
changelogs/fragments/ensure_facts_safe.yml
Normal file
2
changelogs/fragments/ensure_facts_safe.yml
Normal file
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- ensure module results and facts are marked untrusted as templates for safer use within the same task
|
||||
3
changelogs/fragments/gitlab-deprecated-version.yaml
Normal file
3
changelogs/fragments/gitlab-deprecated-version.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
bugfixes:
|
||||
- gitlab modules - Update version deprecations to use strings instead of integers
|
||||
so that ``2.10`` isn't converted to ``2.1``. (https://github.com/ansible/ansible/pull/55395)
|
||||
2
changelogs/fragments/k8s-fix_wait_for_response.yaml
Normal file
2
changelogs/fragments/k8s-fix_wait_for_response.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
minor_changes:
|
||||
- Fix API call to _wait_for_response in k8s modules (https://github.com/ansible/ansible/pull/53937).
|
||||
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- "meraki_static_route - Module would make unnecessary API calls to Meraki when ``net_id`` is specified in task."
|
||||
3
changelogs/fragments/meraki_static_route_api_calls.yml
Normal file
3
changelogs/fragments/meraki_static_route_api_calls.yml
Normal file
@ -0,0 +1,3 @@
|
||||
---
|
||||
bugfixes:
|
||||
- "meraki_static_route - Module would make unnecessary API calls to Meraki when ``net_id`` is specified in task."
|
||||
3
changelogs/fragments/meraki_vlan_api_calls.yml
Normal file
3
changelogs/fragments/meraki_vlan_api_calls.yml
Normal file
@ -0,0 +1,3 @@
|
||||
---
|
||||
bugfixes:
|
||||
- "meraki_vlan - Module would make unnecessary API calls to Meraki when net_id is specified in task."
|
||||
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- Fix invalid src option return response for network config modules (https://github.com/ansible/ansible/pull/56076)
|
||||
2
changelogs/fragments/persistent_loading.yml
Normal file
2
changelogs/fragments/persistent_loading.yml
Normal file
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- pass correct loading context to persistent connections
|
||||
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- postgresql_idx - removed useless rows that remained after the previous refactoring
|
||||
2
changelogs/fragments/postgresql_slot-fix-sslrootcert.yml
Normal file
2
changelogs/fragments/postgresql_slot-fix-sslrootcert.yml
Normal file
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- postgresql_slot - fixed sslrootcert mapping to psycopg2 connection string
|
||||
2
changelogs/fragments/ps-basic-json.yaml
Normal file
2
changelogs/fragments/ps-basic-json.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- Ansible.Basic - Fix issue when deserilizing a JSON string that is not a dictionary - https://github.com/ansible/ansible/pull/55691
|
||||
2
changelogs/fragments/psrp-fetch.yaml
Normal file
2
changelogs/fragments/psrp-fetch.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- psrp - Fix issues when fetching large files causing a memory leak - https://github.com/ansible/ansible/issues/55239
|
||||
3
changelogs/fragments/psrp-output.yaml
Normal file
3
changelogs/fragments/psrp-output.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
bugfixes:
|
||||
- psrp - Fix blank newlines appearing before ``stdout`` when using ``script`` or ``raw`` with the ``psrp`` connection plugin
|
||||
- psrp - Fix issues with propagating errors back to Ansible with ``raw`` tasks
|
||||
2
changelogs/fragments/tower_job_wait-wrong_examples.yml
Normal file
2
changelogs/fragments/tower_job_wait-wrong_examples.yml
Normal file
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- tower_job_wait - Fixed wrong variable specification in examples
|
||||
2
changelogs/fragments/user-aix-shadow-file-parsing.yaml
Normal file
2
changelogs/fragments/user-aix-shadow-file-parsing.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- user - properly parse the shadow file on AIX (https://github.com/ansible/ansible/issues/54461)
|
||||
3
changelogs/fragments/v2.8.0b1_summary.yaml
Normal file
3
changelogs/fragments/v2.8.0b1_summary.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
release_summary: |
|
||||
| Release Date: 2019-04-15
|
||||
| `Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`__
|
||||
3
changelogs/fragments/v2.8.0rc1_summary.yaml
Normal file
3
changelogs/fragments/v2.8.0rc1_summary.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
release_summary: |
|
||||
| Release Date: 2019-04-25
|
||||
| `Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`__
|
||||
3
changelogs/fragments/v2.8.0rc2_summary.yaml
Normal file
3
changelogs/fragments/v2.8.0rc2_summary.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
release_summary: |
|
||||
| Release Date: 2019-05-01
|
||||
| `Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`__
|
||||
3
changelogs/fragments/v2.8.0rc3_summary.yaml
Normal file
3
changelogs/fragments/v2.8.0rc3_summary.yaml
Normal file
@ -0,0 +1,3 @@
|
||||
release_summary: |
|
||||
| Release Date: 2019-05-10
|
||||
| `Porting Guide <https://docs.ansible.com/ansible/devel/porting_guides.html>`__
|
||||
2
changelogs/fragments/vmware_check_ssl_cert.yaml
Normal file
2
changelogs/fragments/vmware_check_ssl_cert.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- vmware - The VMware modules now enable the SSL certificate check unless ``validate_certs`` is ``false``.
|
||||
2
changelogs/fragments/vmware_portgroup_list_host.yml
Normal file
2
changelogs/fragments/vmware_portgroup_list_host.yml
Normal file
@ -0,0 +1,2 @@
|
||||
minor_changes:
|
||||
- vmware_portgroup accepts list of ESXi hostsystem. Modified get_all_host_objs API to accept list of hostsystems.
|
||||
@ -0,0 +1,2 @@
|
||||
minor_changes:
|
||||
- Try to use bundled urllib3 first, then falls back to non-bundled version in vmware_tools (https://github.com/ansible/ansible/pull/55187).
|
||||
@ -0,0 +1,4 @@
|
||||
---
|
||||
bugfixes:
|
||||
- vsphere_guest - creating machines without vm_extra_config allowed
|
||||
- vsphere_guest - powering on/off absent virtual machine will fail
|
||||
2
changelogs/fragments/win_domain-setup.yaml
Normal file
2
changelogs/fragments/win_domain-setup.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- win_domain - Fix checking for a domain introduced in a recent patch
|
||||
2
changelogs/fragments/win_reboot-psrp-command.yaml
Normal file
2
changelogs/fragments/win_reboot-psrp-command.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- win_reboot - pass return value for ``test_command`` result when using the ``psrp`` connection plugin
|
||||
2
changelogs/fragments/win_region-format.yaml
Normal file
2
changelogs/fragments/win_region-format.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
bugfixes:
|
||||
- win_region - Fix the check for ``format`` when running on the ``psrp`` connection plugin
|
||||
@ -275,8 +275,11 @@ def get_plugin_info(module_dir, limit_to=None, verbose=False):
|
||||
module = module.replace("_", "", 1)
|
||||
aliases = module_info[source].get('aliases', set())
|
||||
aliases.add(module)
|
||||
aliases_deprecated = module_info[source].get('aliases_deprecated', set())
|
||||
aliases_deprecated.add(module)
|
||||
# In case we just created this via get()'s fallback
|
||||
module_info[source]['aliases'] = aliases
|
||||
module_info[source]['aliases_deprecated'] = aliases_deprecated
|
||||
continue
|
||||
else:
|
||||
# Handle deprecations
|
||||
@ -340,6 +343,7 @@ def get_plugin_info(module_dir, limit_to=None, verbose=False):
|
||||
'source': os.path.relpath(module_path, module_dir),
|
||||
'deprecated': deprecated,
|
||||
'aliases': module_info[module].get('aliases', set()),
|
||||
'aliases_deprecated': module_info[module].get('aliases_deprecated', set()),
|
||||
'metadata': metadata,
|
||||
'doc': doc,
|
||||
'examples': examples,
|
||||
@ -404,6 +408,7 @@ def jinja2_environment(template_dir, typ, plugin_type):
|
||||
env.filters['documented_type'] = documented_type
|
||||
env.tests['list'] = test_list
|
||||
templates['plugin'] = env.get_template('plugin.rst.j2')
|
||||
templates['plugin_deprecation_stub'] = env.get_template('plugin_deprecation_stub.rst.j2')
|
||||
|
||||
if plugin_type == 'module':
|
||||
name = 'modules'
|
||||
@ -570,6 +575,26 @@ def process_plugins(module_map, templates, outputname, output_dir, ansible_versi
|
||||
|
||||
write_data(text, output_dir, outputname, module)
|
||||
|
||||
# Create deprecation stub pages for deprecated aliases
|
||||
if module_map[module]['aliases']:
|
||||
for alias in module_map[module]['aliases']:
|
||||
if alias in module_map[module]['aliases_deprecated']:
|
||||
doc['alias'] = alias
|
||||
|
||||
display.v('about to template %s (deprecation alias %s)' % (module, alias))
|
||||
display.vvvvv(pp.pformat(doc))
|
||||
try:
|
||||
text = templates['plugin_deprecation_stub'].render(doc)
|
||||
except Exception as e:
|
||||
display.warning(msg="Could not parse %s (deprecation alias %s) due to %s" % (module, alias, e))
|
||||
continue
|
||||
|
||||
if LooseVersion(jinja2.__version__) < LooseVersion('2.10'):
|
||||
# jinja2 < 2.10's indent filter indents blank lines. Cleanup
|
||||
text = re.sub(' +\n', '\n', text)
|
||||
|
||||
write_data(text, output_dir, outputname, alias)
|
||||
|
||||
|
||||
def process_categories(plugin_info, categories, templates, output_dir, output_name, plugin_type):
|
||||
# For some reason, this line is changing plugin_info:
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
Homepage and documentation source for Ansible
|
||||
Homepage and Documentation Source for Ansible
|
||||
=============================================
|
||||
|
||||
This project hosts the source behind [docs.ansible.com](https://docs.ansible.com/)
|
||||
@ -15,7 +15,7 @@ If you do not want to learn the reStructuredText format, you can also [file issu
|
||||
|
||||
Note that module documentation can actually be [generated from a DOCUMENTATION docstring][module-docs] in the modules directory, so corrections to modules written as such need to be made in the module source, rather than in docsite source.
|
||||
|
||||
To install sphinx and the required theme, install pip and then "pip install sphinx sphinx_rtd_theme"
|
||||
To install sphinx and the required theme, install ``pip`` and then ``pip install sphinx sphinx_rtd_theme``
|
||||
|
||||
[file issues]: https://github.com/ansible/ansible/issues
|
||||
[module-docs]: https://docs.ansible.com/developing_modules.html#documenting-your-module
|
||||
@ -23,7 +23,7 @@ To install sphinx and the required theme, install pip and then "pip install sphi
|
||||
HEADERS
|
||||
=======
|
||||
|
||||
RST allows for arbitrary hierchy for the headers, it will 'learn on the fly' but we want a standard so all our documents can follow:
|
||||
RST allows for arbitrary hierarchy for the headers, it will 'learn on the fly'. We also want a standard that all our documents can follow:
|
||||
|
||||
```
|
||||
##########################
|
||||
|
||||
@ -156,7 +156,7 @@
|
||||
<div class="DocSiteProduct-logoText">
|
||||
Ansible
|
||||
<div class="DocSiteProduct-CurrentVersion" align="right">
|
||||
devel
|
||||
2.8
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1758,7 +1758,7 @@ footer span.commit code,footer span.commit .rst-content tt,.rst-content footer s
|
||||
.rst-content .sidebar p,.rst-content .sidebar ul,.rst-content .sidebar dl{font-size:90%}
|
||||
.rst-content .sidebar .last{margin-bottom:0}
|
||||
.rst-content .sidebar .sidebar-title{display:block;font-family:"Roboto Slab","ff-tisa-web-pro","Georgia",Arial,sans-serif;font-weight:bold;background:#e1e4e5;padding:6px 12px;margin:-24px;margin-bottom:24px;font-size:100%}
|
||||
.rst-content .highlighted{background:#F1C40F;display:inline-block;font-weight:bold;padding:0 6px}
|
||||
.rst-content .highlighted{background:#F1C40F;display:inline-block;font-weight:bold;}
|
||||
.rst-content .footnote-reference,.rst-content .citation-reference{vertical-align:baseline;position:relative;top:-0.4em;line-height:0;font-size:90%}
|
||||
.rst-content table.docutils.citation,.rst-content table.docutils.footnote{background:none;border:none;color:gray}
|
||||
.rst-content table.docutils.citation td,.rst-content table.docutils.citation tr,.rst-content table.docutils.footnote td,.rst-content table.docutils.footnote tr{border:none;background-color:transparent !important;white-space:normal}
|
||||
|
||||
@ -5,7 +5,9 @@
|
||||
Contributing your module to Ansible
|
||||
***********************************
|
||||
|
||||
If you want to contribute a module to Ansible, you must meet our objective and subjective requirements. Modules accepted into the `main project repo <https://github.com/ansible/ansible>`_ ship with every Ansible installation. However, contributing to the main project isn't the only way to distribute a module - you can embed modules in roles on Galaxy or simply share copies of your module code for :ref:`local use <developing_locally>`.
|
||||
If you want to contribute a module to Ansible, you must meet our objective and subjective requirements. Please read the details below, and also review our :ref:`tips for module development <developing_modules_best_practices>`.
|
||||
|
||||
Modules accepted into the `main project repo <https://github.com/ansible/ansible>`_ ship with every Ansible installation. However, contributing to the main project isn't the only way to distribute a module - you can embed modules in roles on Galaxy or simply share copies of your module code for :ref:`local use <developing_locally>`.
|
||||
|
||||
Contributing to Ansible: objective requirements
|
||||
===============================================
|
||||
@ -37,5 +39,6 @@ If your module meets our objective requirements, we'll review your code to see i
|
||||
Other checklists
|
||||
================
|
||||
|
||||
* :ref:`Tips for module development <developing_modules_best_practices>`.
|
||||
* `Amazon development checklist <https://github.com/ansible/ansible/blob/devel/lib/ansible/modules/cloud/amazon/GUIDELINES.md>`_.
|
||||
* :ref:`Windows development checklist <developing_modules_general_windows>`.
|
||||
|
||||
@ -31,6 +31,7 @@ Find the task that best describes what you want to do:
|
||||
* I want to :ref:`debug my module code <debugging>`.
|
||||
* I want to :ref:`add tests <developing_testing>`.
|
||||
* I want to :ref:`document my module <module_documenting>`.
|
||||
* I want to follow :ref:`conventions and tips for clean, usable module code <developing_modules_best_practices>`.
|
||||
* I want to :ref:`make sure my code runs on Python 2 and Python 3 <developing_python_3>`.
|
||||
|
||||
* I want to work on other development projects:
|
||||
|
||||
@ -43,6 +43,11 @@ Or against a specific Python version by doing:
|
||||
|
||||
ansible-test units --tox --python 2.7 apt
|
||||
|
||||
If you are running unit tests against things other than modules, such as module utilities, specify the whole file path:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
ansible-test units --tox test/units/module_utils/basic/test_imports.py
|
||||
|
||||
For advanced usage see the online help::
|
||||
|
||||
|
||||
@ -190,8 +190,9 @@ above, either by throwing an exception or ensuring that they haven't been called
|
||||
class AnsibleExitJson(Exception):
|
||||
"""Exception class to be raised by module.exit_json and caught by the test case"""
|
||||
pass
|
||||
#you may also do the same to fail json
|
||||
module=MagicMock()
|
||||
|
||||
# you may also do the same to fail json
|
||||
module = MagicMock()
|
||||
module.exit_json.side_effect = AnsibleExitJson(Exception)
|
||||
with self.assertRaises(AnsibleExitJson) as result:
|
||||
return = my_module.test_this_function(module, argument)
|
||||
@ -287,27 +288,22 @@ Passing Arguments
|
||||
.. This section should be updated once https://github.com/ansible/ansible/pull/31456 is
|
||||
closed since the function below will be provided in a library file.
|
||||
|
||||
To pass arguments to a module correctly, use a function that stores the
|
||||
parameters in a special string variable. Module creation and argument processing is
|
||||
To pass arguments to a module correctly, use the ``set_module_args`` method which accepts a dictionary
|
||||
as its parameter. Module creation and argument processing is
|
||||
handled through the :class:`AnsibleModule` object in the basic section of the utilities. Normally
|
||||
this accepts input on ``STDIN``, which is not convenient for unit testing. When the special
|
||||
variable is set it will be treated as if the input came on ``STDIN`` to the module.::
|
||||
variable is set it will be treated as if the input came on ``STDIN`` to the module. Simply call that function before setting up your module::
|
||||
|
||||
import json
|
||||
from ansible.module_utils._text import to_bytes
|
||||
import json
|
||||
from units.modules.utils import set_module_args
|
||||
from ansible.module_utils._text import to_bytes
|
||||
|
||||
def set_module_args(args):
|
||||
args = json.dumps({'ANSIBLE_MODULE_ARGS': args})
|
||||
basic._ANSIBLE_ARGS = to_bytes(args)
|
||||
|
||||
simply call that function before setting up your module
|
||||
|
||||
def test_already_registered(self):
|
||||
set_module_args({
|
||||
'activationkey': 'key',
|
||||
'username': 'user',
|
||||
'password': 'pass',
|
||||
})
|
||||
def test_already_registered(self):
|
||||
set_module_args({
|
||||
'activationkey': 'key',
|
||||
'username': 'user',
|
||||
'password': 'pass',
|
||||
})
|
||||
|
||||
Handling exit correctly
|
||||
-----------------------
|
||||
@ -334,8 +330,9 @@ testing for the correct exception::
|
||||
'username': 'user',
|
||||
'password': 'pass',
|
||||
})
|
||||
with self.assertRaises(AnsibleExitJson) as result:
|
||||
my_module.main()
|
||||
|
||||
with self.assertRaises(AnsibleExitJson) as result:
|
||||
my_module.main()
|
||||
|
||||
The same technique can be used to replace :meth:`module.fail_json` (which is used for failure
|
||||
returns from modules) and for the ``aws_module.fail_json_aws()`` (used in modules for Amazon
|
||||
@ -349,7 +346,7 @@ the arguments as above, set up the appropriate exit exception and then run the m
|
||||
|
||||
# This test is based around pytest's features for individual test functions
|
||||
import pytest
|
||||
import ansible.modules.module.group.my_modulle as my_module
|
||||
import ansible.modules.module.group.my_module as my_module
|
||||
|
||||
def test_main_function(monkeypatch):
|
||||
monkeypatch.setattr(my_module.AnsibleModule, "exit_json", fake_exit_json)
|
||||
@ -511,7 +508,7 @@ This now makes it possible to run tests against the module initiation function::
|
||||
})
|
||||
|
||||
with self.assertRaises(AnsibleFailJson) as result:
|
||||
self.module.setup_json
|
||||
self.module.setup_json
|
||||
|
||||
See also ``test/units/module_utils/aws/test_rds.py``
|
||||
|
||||
@ -559,8 +556,8 @@ the code in Ansible to trigger that failure.
|
||||
General advice on testing Python code
|
||||
`Uncle Bob's many videos on YouTube <https://www.youtube.com/watch?v=QedpQjxBPMA&list=PLlu0CT-JnSasQzGrGzddSczJQQU7295D2>`_
|
||||
Unit testing is a part of the of various philosophies of software development, including
|
||||
Extreme Programming (XP), Clean Coding. Uncle Bob talks through how to benfit from this
|
||||
`"Why Most Unit Testing is Waste" https://rbcs-us.com/documents/Why-Most-Unit-Testing-is-Waste.pdf`
|
||||
Extreme Programming (XP), Clean Coding. Uncle Bob talks through how to benefit from this
|
||||
`"Why Most Unit Testing is Waste" <https://rbcs-us.com/documents/Why-Most-Unit-Testing-is-Waste.pdf>`_
|
||||
An article warning against the costs of unit testing
|
||||
`'A Response to "Why Most Unit Testing is Waste"' https://henrikwarne.com/2014/09/04/a-response-to-why-most-unit-testing-is-waste/`
|
||||
`'A Response to "Why Most Unit Testing is Waste"' <https://henrikwarne.com/2014/09/04/a-response-to-why-most-unit-testing-is-waste/>`_
|
||||
An response pointing to how to maintain the value of unit tests
|
||||
|
||||
@ -55,7 +55,7 @@ Or for the openstack plugin the file has to be called ``clouds.yml`` or ``openst
|
||||
# clouds.yml or openstack.(yml|yaml)
|
||||
plugin: openstack
|
||||
|
||||
The ``auto`` inventory plugin is enabled by default and works by using the ``plugin`` field to indicate the plugin that should attempt to parse it. You can configure the whitelist/precedence of inventory plugins used to parse source using the `ansible.cfg` ['inventory'] ``enable_plugins`` list. After enabling the plugin and providing any required options you can view the populated inventory with ``ansible-inventory -i demo.aws_ec2.yml --graph``:
|
||||
The ``auto`` inventory plugin is enabled by default and works by using the ``plugin`` field to indicate the plugin that should attempt to parse it. You can configure the whitelist/precedence of inventory plugins used to parse source using the `ansible.cfg` ['inventory'] ``enable_plugins`` list. After enabling the plugin and providing any required options, you can view the populated inventory with ``ansible-inventory -i demo.aws_ec2.yml --graph``:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
|
||||
@ -8,7 +8,7 @@ This section discusses the behavioral changes between Ansible 2.7 and Ansible 2.
|
||||
|
||||
It is intended to assist in updating your playbooks, plugins and other parts of your Ansible infrastructure so they will work with this version of Ansible.
|
||||
|
||||
We suggest you read this page along with `Ansible Changelog for 2.8 <https://github.com/ansible/ansible/blob/devel/changelogs/CHANGELOG-v2.8.rst>`_ to understand what updates you may need to make.
|
||||
We suggest you read this page along with `Ansible Changelog for 2.8 <https://github.com/ansible/ansible/blob/stable-2.8/changelogs/CHANGELOG-v2.8.rst>`_ to understand what updates you may need to make.
|
||||
|
||||
This document is part of a collection on porting. The complete list of porting guides can be found at :ref:`porting guides <porting_guides>`.
|
||||
|
||||
@ -236,8 +236,16 @@ The following modules will be removed in Ansible 2.12. Please update your playbo
|
||||
* ``foreman`` use `foreman-ansible-modules <https://github.com/theforeman/foreman-ansible-modules>`_ instead.
|
||||
* ``katello`` use `foreman-ansible-modules <https://github.com/theforeman/foreman-ansible-modules>`_ instead.
|
||||
* ``github_hooks`` use :ref:`github_webhook <github_webhook_module>` and :ref:`github_webhook_facts <github_webhook_facts_module>` instead.
|
||||
* ``digital_ocean`` use :ref:`digital_ocean_droplet <digital_ocean_droplet_module>` instead.
|
||||
* ``gce`` use :ref:`gcp_compute_instance <gcp_compute_instance_module>` instead.
|
||||
* ``digital_ocean`` use :ref `digital_ocean_droplet <digital_ocean_droplet_module>` instead.
|
||||
* ``gce`` use :ref `gcp_compute_instance <gcp_compute_instance_module>` instead.
|
||||
* ``gcspanner`` use :ref `gcp_spanner_instance <gcp_spanner_instance_module>` and :ref `gcp_spanner_database <gcp_spanner_database_module>` instead.
|
||||
* ``gcdns_record`` use :ref `gcp_dns_resource_record_set <gcp_dns_resource_record_set_module>` instead.
|
||||
* ``gcdns_zone`` use :ref `gcp_dns_managed_zone <gcp_dns_managed_zone_module>` instead.
|
||||
* ``gcp_forwarding_rule`` use :ref `gcp_compute_global_forwarding_rule <gcp_compute_global_forwarding_rule_module>` or :ref `gcp_compute_forwarding_rule <gcp_compute_forwarding_rule_module>` instead.
|
||||
* ``gcp_healthcheck`` use :ref `gcp_compute_health_check <gcp_compute_health_check__module>`, :ref `gcp_compute_http_health_check <gcp_compute_http_health_check_module>`, or :ref `gcp_compute_https_health_check <gcp_compute_https_health_check_module>` instead.
|
||||
* ``gcp_backend_service`` use :ref `gcp_compute_backend_service <gcp_compute_backend_service_module>` instead.
|
||||
* ``gcp_target_proxy`` use :ref `gcp_compute_target_proxy <gcp_compute_target_proxy_module>` instead.
|
||||
* ``gcp_url_map`` use :ref `gcp_compute_url_map <gcp_compute_url_map_module>` instead.
|
||||
* ``panos`` use the `Palo Alto Networks Ansible Galaxy role <https://galaxy.ansible.com/PaloAltoNetworks/paloaltonetworks>`_ instead.
|
||||
|
||||
|
||||
|
||||
@ -231,11 +231,11 @@ There are a few common errors that one might run into when trying to execute Ans
|
||||
|
||||
To get around this limitation, download and install a later version of `python for z/OS <https://www.rocketsoftware.com/zos-open-source>`_ (2.7.13 or 3.6.1) that represents strings internally as ASCII. Version 2.7.13 is verified to work.
|
||||
|
||||
* When ``pipelining = False`` in `/etc/ansible/ansible.cfg` then Ansible modules are transferred in binary mode via sftp however execution of python fails with
|
||||
* When ``pipelining = False`` in `/etc/ansible/ansible.cfg` then Ansible modules are transferred in binary mode via sftp however execution of python fails with
|
||||
|
||||
.. error::
|
||||
SyntaxError: Non-UTF-8 code starting with \'\\x83\' in file /a/user1/.ansible/tmp/ansible-tmp-1548232945.35-274513842609025/AnsiballZ_stat.py on line 1, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
|
||||
|
||||
|
||||
To fix it set ``pipelining = True`` in `/etc/ansible/ansible.cfg`.
|
||||
|
||||
* Python interpret cannot be found in default location ``/usr/bin/python`` on target host.
|
||||
@ -643,6 +643,32 @@ but you can still access the original via ``hostvars``::
|
||||
This works for all overriden connection variables, like ``ansible_user``, ``ansible_port``, etc.
|
||||
|
||||
|
||||
.. _scp_protocol_error_filename:
|
||||
|
||||
How do I fix 'protocol error: filename does not match request' when fetching a file?
|
||||
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
Newer releases of OpenSSH have a `bug <https://bugzilla.mindrot.org/show_bug.cgi?id=2966>`_ in the SCP client that can trigger this error on the Ansible controller when using SCP as the file transfer mechanism::
|
||||
|
||||
failed to transfer file to /tmp/ansible/file.txt\r\nprotocol error: filename does not match request
|
||||
|
||||
In these releases, SCP tries to validate that the path of the file to fetch matches the requested path.
|
||||
The validation
|
||||
fails if the remote filename requires quotes to escape spaces or non-ascii characters in its path. To avoid this error:
|
||||
|
||||
* Use SFTP instead of SCP by setting ``scp_if_ssh`` to ``smart`` (which tries SFTP first) or to ``False``. You can do this in one of four ways:
|
||||
* Rely on the default setting, which is ``smart`` - this works if ``scp_if_ssh`` is not explicitly set anywhere
|
||||
* Set a :ref:`host variable <host_variables>` or :ref:`group variable <group_variables>` in inventory: ``ansible_scp_if_ssh: False``
|
||||
* Set an environment variable on your control node: ``export ANSIBLE_SCP_IF_SSH=False``
|
||||
* Pass an environment variable when you run Ansible: ``ANSIBLE_SCP_IF_SSH=smart ansible-playbook``
|
||||
* Modify your ``ansible.cfg`` file: add ``scp_if_ssh=False`` to the ``[ssh_connection]`` section
|
||||
* If you must use SCP, set the ``-T`` arg to tell the SCP client to ignore path validation. You can do this in one of three ways:
|
||||
* Set a :ref:`host variable <host_variables>` or :ref:`group variable <group_variables>`: ``ansible_scp_extra_args=-T``,
|
||||
* Export or pass an environment variable: ``ANSIBLE_SCP_EXTRA_ARGS=-T``
|
||||
* Modify your ``ansible.cfg`` file: add ``scp_extra_args=-T`` to the ``[ssh_connection]`` section
|
||||
|
||||
.. note:: If you see an ``invalid argument`` error when using ``-T``, then your SCP client is not performing filename validation and will not trigger this error.
|
||||
|
||||
.. _i_dont_see_my_question:
|
||||
|
||||
I don't see my question here
|
||||
|
||||
@ -18,7 +18,6 @@ Whereas classically ansible will execute tasks in its host loop against multiple
|
||||
In your playbook steps we'll typically be using the following pattern for provisioning steps::
|
||||
|
||||
- hosts: localhost
|
||||
connection: local
|
||||
gather_facts: False
|
||||
tasks:
|
||||
- ...
|
||||
@ -68,7 +67,6 @@ instance.::
|
||||
# demo_setup.yml
|
||||
|
||||
- hosts: localhost
|
||||
connection: local
|
||||
gather_facts: False
|
||||
|
||||
tasks:
|
||||
@ -94,7 +92,6 @@ From this, we'll use the add_host module to dynamically create a host group cons
|
||||
# demo_setup.yml
|
||||
|
||||
- hosts: localhost
|
||||
connection: local
|
||||
gather_facts: False
|
||||
|
||||
tasks:
|
||||
|
||||
@ -81,14 +81,13 @@ For the GCE modules you can specify the credentials as arguments:
|
||||
* ``project``: id of the project
|
||||
* ``scopes``: The specific scopes that you want the actions to use.
|
||||
|
||||
For example, to create a new IP address using the `gcp_compute_address` module,
|
||||
For example, to create a new IP address using the ``gcp_compute_address`` module,
|
||||
you can use the following configuration:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- name: Create IP address
|
||||
hosts: localhost
|
||||
connection: local
|
||||
gather_facts: no
|
||||
|
||||
vars:
|
||||
@ -169,7 +168,6 @@ rest.
|
||||
- name: Create an instance
|
||||
hosts: localhost
|
||||
gather_facts: no
|
||||
connection: local
|
||||
vars:
|
||||
project: my-project
|
||||
auth_kind: serviceaccount
|
||||
@ -254,3 +252,60 @@ Note that use of the "add_host" module above creates a temporary, in-memory grou
|
||||
in the 'new_instances' group, if so desired. Any sort of arbitrary configuration is possible at this point.
|
||||
|
||||
For more information about Google Cloud, please visit the `Google Cloud website <https://cloud.google.com>`_.
|
||||
|
||||
Migration Guides
|
||||
----------------
|
||||
|
||||
gce.py -> gcp_compute_instance.py
|
||||
`````````````````````````````````
|
||||
As of Ansible 2.8, we're encouraging everyone to move from the ``gce`` module to the
|
||||
``gcp_compute_instance`` module. The ``gcp_compute_instance`` module has better
|
||||
support for all of GCP's features, fewer dependencies, more flexibility, and
|
||||
better supports GCP's authentication systems.
|
||||
|
||||
The ``gcp_compute_instance`` module supports all of the features of the ``gce``
|
||||
module (and more!). Below is a mapping of ``gce`` fields over to
|
||||
``gcp_compute_instance`` fields.
|
||||
|
||||
============================ ========================================== ======================
|
||||
gce.py gcp_compute_instance.py Notes
|
||||
============================ ========================================== ======================
|
||||
state state/status State on gce has multiple values: "present", "absent", "stopped", "started", "terminated". State on gcp_compute_instance is used to describe if the instance exists (present) or does not (absent). Status is used to describe if the instance is "started", "stopped" or "terminated".
|
||||
image disks[].initialize_params.source_image You'll need to create a single disk using the disks[] parameter and set it to be the boot disk (disks[].boot = true)
|
||||
image_family disks[].initialize_params.source_image See above.
|
||||
external_projects disks[].initialize_params.source_image The name of the source_image will include the name of the project.
|
||||
instance_names Use a loop or multiple tasks. Using loops is a more Ansible-centric way of creating multiple instances and gives you the most flexibility.
|
||||
service_account_email service_accounts[].email This is the service_account email address that you want the instance to be associated with. It is not the service_account email address that is used for the credentials necessary to create the instance.
|
||||
service_account_permissions service_accounts[].scopes These are the permissions you want to grant to the instance.
|
||||
pem_file Not supported. We recommend using JSON service account credentials instead of PEM files.
|
||||
credentials_file service_account_file
|
||||
project_id project
|
||||
name name This field does not accept an array of names. Use a loop to create multiple instances.
|
||||
num_instances Use a loop For maximum flexibility, we're encouraging users to use Ansible features to create multiple instances, rather than letting the module do it for you.
|
||||
network network_interfaces[].network
|
||||
subnetwork network_interfaces[].subnetwork
|
||||
persistent_boot_disk disks[].type = 'PERSISTENT'
|
||||
disks disks[]
|
||||
ip_forward can_ip_forward
|
||||
external_ip network_interfaces[].access_configs.nat_ip This field takes multiple types of values. You can create an IP address with ``gcp_compute_address`` and place the name/output of the address here. You can also place the string value of the IP address's GCP name or the actual IP address.
|
||||
disks_auto_delete disks[].auto_delete
|
||||
preemptible scheduling.preemptible
|
||||
disk_size disks[].initialize_params.disk_size_gb
|
||||
============================ ========================================== ======================
|
||||
|
||||
An example playbook is below:
|
||||
|
||||
.. code:: yaml
|
||||
|
||||
gcp_compute_instance:
|
||||
name: "{{ item }}"
|
||||
machine_type: n1-standard-1
|
||||
... # any other settings
|
||||
zone: us-central1-a
|
||||
project: "my-project"
|
||||
auth_kind: "service_account_file"
|
||||
service_account_file: "~/my_account.json"
|
||||
state: present
|
||||
with_items:
|
||||
- instance-1
|
||||
- instance-2
|
||||
|
||||
@ -15,7 +15,7 @@ Windows host must meet the following requirements:
|
||||
* Ansible's supported Windows versions generally match those under current
|
||||
and extended support from Microsoft. Supported desktop OSs include
|
||||
Windows 7, 8.1, and 10, and supported server OSs are Windows Server 2008,
|
||||
2008 R2, 2012, 2012 R2, and 2016.
|
||||
2008 R2, 2012, 2012 R2, 2016, and 2019.
|
||||
|
||||
* Ansible requires PowerShell 3.0 or newer and at least .NET 4.0 to be
|
||||
installed on the Windows host.
|
||||
|
||||
18
docs/templates/plugin_deprecation_stub.rst.j2
vendored
Normal file
18
docs/templates/plugin_deprecation_stub.rst.j2
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
:source: @{ source }@
|
||||
|
||||
{# avoids rST "isn't included in any toctree" errors for module docs #}
|
||||
:orphan:
|
||||
|
||||
.. _@{ module }@_@{ plugin_type }@_alias_@{ alias }@:
|
||||
|
||||
{% if short_description %}
|
||||
{% set title = alias + ' -- ' + short_description | rst_ify %}
|
||||
{% else %}
|
||||
{% set title = alias %}
|
||||
{% endif %}
|
||||
|
||||
@{ title }@
|
||||
@{ '+' * title|length }@
|
||||
|
||||
This is an alias for :ref:`@{ module }@ <@{ module }@_@{ plugin_type }@>`.
|
||||
This name has been **deprecated**. Please update your tasks to use the new name ``@{ module }@`` instead.
|
||||
@ -9,7 +9,6 @@ __metaclass__ = type
|
||||
|
||||
import getpass
|
||||
import os
|
||||
import os.path
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
@ -219,7 +219,7 @@ $($ErrorRecord.InvocationInfo.PositionMessage)
|
||||
$b64_output = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($output))
|
||||
Write-Output -InputObject $b64_output
|
||||
} else {
|
||||
Write-Output -InputObject $output
|
||||
$output
|
||||
}
|
||||
} catch {
|
||||
Write-AnsibleError -Message "internal error: failed to run exec_wrapper action $action" -ErrorRecord $_
|
||||
|
||||
@ -692,9 +692,10 @@ class TaskExecutor:
|
||||
vars_copy.update(result['ansible_facts'])
|
||||
else:
|
||||
# TODO: cleaning of facts should eventually become part of taskresults instead of vars
|
||||
vars_copy.update(namespace_facts(result['ansible_facts']))
|
||||
af = wrap_var(result['ansible_facts'])
|
||||
vars_copy.update(namespace_facts(af))
|
||||
if C.INJECT_FACTS_AS_VARS:
|
||||
vars_copy.update(clean_facts(result['ansible_facts']))
|
||||
vars_copy.update(clean_facts(af))
|
||||
|
||||
# set the failed property if it was missing.
|
||||
if 'failed' not in result:
|
||||
@ -754,9 +755,10 @@ class TaskExecutor:
|
||||
variables.update(result['ansible_facts'])
|
||||
else:
|
||||
# TODO: cleaning of facts should eventually become part of taskresults instead of vars
|
||||
variables.update(namespace_facts(result['ansible_facts']))
|
||||
af = wrap_var(result['ansible_facts'])
|
||||
variables.update(namespace_facts(af))
|
||||
if C.INJECT_FACTS_AS_VARS:
|
||||
variables.update(clean_facts(result['ansible_facts']))
|
||||
variables.update(clean_facts(af))
|
||||
|
||||
# save the notification target in the result, if it was specified, as
|
||||
# this task may be running in a loop in which case the notification
|
||||
|
||||
@ -29,6 +29,7 @@ import traceback
|
||||
|
||||
from ansible.module_utils._text import to_native, to_text, to_bytes
|
||||
from ansible.module_utils.urls import fetch_url
|
||||
from ansible.module_utils.compat import ipaddress as compat_ipaddress
|
||||
|
||||
try:
|
||||
import cryptography
|
||||
@ -46,7 +47,7 @@ try:
|
||||
HAS_CURRENT_CRYPTOGRAPHY = (LooseVersion(CRYPTOGRAPHY_VERSION) >= LooseVersion('1.5'))
|
||||
if HAS_CURRENT_CRYPTOGRAPHY:
|
||||
_cryptography_backend = cryptography.hazmat.backends.default_backend()
|
||||
except Exception as _:
|
||||
except Exception as dummy:
|
||||
HAS_CURRENT_CRYPTOGRAPHY = False
|
||||
|
||||
|
||||
@ -90,7 +91,7 @@ def write_file(module, dest, content):
|
||||
except Exception as err:
|
||||
try:
|
||||
f.close()
|
||||
except Exception as e:
|
||||
except Exception as dummy:
|
||||
pass
|
||||
os.remove(tmpsrc)
|
||||
raise ModuleFailException("failed to create temporary content file: %s" % to_native(err), exception=traceback.format_exc())
|
||||
@ -101,7 +102,7 @@ def write_file(module, dest, content):
|
||||
if not os.path.exists(tmpsrc):
|
||||
try:
|
||||
os.remove(tmpsrc)
|
||||
except Exception as e:
|
||||
except Exception as dummy:
|
||||
pass
|
||||
raise ModuleFailException("Source %s does not exist" % (tmpsrc))
|
||||
if not os.access(tmpsrc, os.R_OK):
|
||||
@ -174,7 +175,7 @@ def _parse_key_openssl(openssl_binary, module, key_file=None, key_content=None):
|
||||
except Exception as err:
|
||||
try:
|
||||
f.close()
|
||||
except Exception as e:
|
||||
except Exception as dummy:
|
||||
pass
|
||||
raise ModuleFailException("failed to create temporary content file: %s" % to_native(err), exception=traceback.format_exc())
|
||||
f.close()
|
||||
@ -824,44 +825,11 @@ class ACMEAccount(object):
|
||||
|
||||
|
||||
def _normalize_ip(ip):
|
||||
if ':' not in ip:
|
||||
# For IPv4 addresses: remove trailing zeros per nibble
|
||||
ip = '.'.join([nibble.lstrip('0') or '0' for nibble in ip.split('.')])
|
||||
try:
|
||||
return to_native(compat_ipaddress.ip_address(to_text(ip)).compressed)
|
||||
except ValueError:
|
||||
# We don't want to error out on something IPAddress() can't parse
|
||||
return ip
|
||||
# For IPv6 addresses:
|
||||
# 1. Make them lowercase and split
|
||||
ip = ip.lower()
|
||||
i = ip.find('::')
|
||||
if i >= 0:
|
||||
front = ip[:i].split(':') or []
|
||||
back = ip[i + 2:].split(':') or []
|
||||
ip = front + ['0'] * (8 - len(front) - len(back)) + back
|
||||
else:
|
||||
ip = ip.split(':')
|
||||
# 2. Remove trailing zeros per nibble
|
||||
ip = [nibble.lstrip('0') or '0' for nibble in ip]
|
||||
# 3. Find longest consecutive sequence of zeros
|
||||
zeros_start = -1
|
||||
zeros_length = -1
|
||||
current_start = -1
|
||||
for i, nibble in enumerate(ip):
|
||||
if nibble == '0':
|
||||
if current_start < 0:
|
||||
current_start = i
|
||||
elif current_start >= 0:
|
||||
if i - current_start > zeros_length:
|
||||
zeros_start = current_start
|
||||
zeros_length = i - current_start
|
||||
current_start = -1
|
||||
if current_start >= 0:
|
||||
if 8 - current_start > zeros_length:
|
||||
zeros_start = current_start
|
||||
zeros_length = 8 - current_start
|
||||
# 4. If the sequence has at least two elements, contract
|
||||
if zeros_length >= 2:
|
||||
return ':'.join(ip[:zeros_start]) + '::' + ':'.join(ip[zeros_start + zeros_length:])
|
||||
# 5. If not, return full IP
|
||||
return ':'.join(ip)
|
||||
|
||||
|
||||
def openssl_get_csr_identifiers(openssl_binary, module, csr_filename):
|
||||
@ -910,7 +878,7 @@ def cryptography_get_csr_identifiers(module, csr_filename):
|
||||
if isinstance(name, cryptography.x509.DNSName):
|
||||
identifiers.add(('dns', name.value))
|
||||
elif isinstance(name, cryptography.x509.IPAddress):
|
||||
identifiers.add(('ip', _normalize_ip(str(name.value))))
|
||||
identifiers.add(('ip', name.value.compressed))
|
||||
else:
|
||||
raise ModuleFailException('Found unsupported SAN identifier {0}'.format(name))
|
||||
return identifiers
|
||||
@ -952,7 +920,7 @@ def set_crypto_backend(module):
|
||||
elif backend == 'cryptography':
|
||||
try:
|
||||
cryptography.__version__
|
||||
except Exception as _:
|
||||
except Exception as dummy:
|
||||
module.fail_json(msg='Cannot find cryptography module!')
|
||||
HAS_CURRENT_CRYPTOGRAPHY = True
|
||||
else:
|
||||
|
||||
@ -27,7 +27,7 @@ AZURE_COMMON_ARGS = dict(
|
||||
choices=['auto', 'cli', 'env', 'credential_file', 'msi']
|
||||
),
|
||||
profile=dict(type='str'),
|
||||
subscription_id=dict(type='str', no_log=True),
|
||||
subscription_id=dict(type='str'),
|
||||
client_id=dict(type='str', no_log=True),
|
||||
secret=dict(type='str', no_log=True),
|
||||
tenant=dict(type='str', no_log=True),
|
||||
|
||||
@ -2674,7 +2674,3 @@ class AnsibleModule(object):
|
||||
|
||||
def get_module_path():
|
||||
return os.path.dirname(os.path.realpath(__file__))
|
||||
|
||||
|
||||
def get_timestamp():
|
||||
return datetime.datetime.now().replace(microsecond=0).isoformat()
|
||||
|
||||
@ -334,7 +334,7 @@ namespace Ansible.Basic
|
||||
LogEvent(String.Format("[WARNING] {0}", message), EventLogEntryType.Warning);
|
||||
}
|
||||
|
||||
public static Dictionary<string, object> FromJson(string json) { return FromJson<Dictionary<string, object>>(json); }
|
||||
public static object FromJson(string json) { return FromJson<object>(json); }
|
||||
public static T FromJson<T>(string json)
|
||||
{
|
||||
#if CORECLR
|
||||
@ -375,7 +375,7 @@ namespace Ansible.Basic
|
||||
if (args.Length > 0)
|
||||
{
|
||||
string inputJson = File.ReadAllText(args[0]);
|
||||
Dictionary<string, object> rawParams = FromJson(inputJson);
|
||||
Dictionary<string, object> rawParams = FromJson<Dictionary<string, object>>(inputJson);
|
||||
if (!rawParams.ContainsKey("ANSIBLE_MODULE_ARGS"))
|
||||
throw new ArgumentException("Module was unable to get ANSIBLE_MODULE_ARGS value from the argument path json");
|
||||
return (IDictionary)rawParams["ANSIBLE_MODULE_ARGS"];
|
||||
|
||||
@ -6,7 +6,7 @@ import json
|
||||
from time import sleep
|
||||
|
||||
try:
|
||||
from docker.errors import APIError
|
||||
from docker.errors import APIError, NotFound
|
||||
except ImportError:
|
||||
# missing Docker SDK for Python handled in ansible.module_utils.docker.common
|
||||
pass
|
||||
@ -259,15 +259,16 @@ class AnsibleDockerSwarmClient(AnsibleDockerClient):
|
||||
Single service information structure
|
||||
"""
|
||||
try:
|
||||
service_info = self.inspect_service(service=service_id)
|
||||
service_info = self.inspect_service(service_id)
|
||||
except NotFound as exc:
|
||||
if skip_missing is False:
|
||||
self.fail("Error while reading from Swarm manager: %s" % to_native(exc))
|
||||
else:
|
||||
return None
|
||||
except APIError as exc:
|
||||
if exc.status_code == 503:
|
||||
self.fail("Cannot inspect service: To inspect service execute module on Swarm Manager")
|
||||
if exc.status_code == 404:
|
||||
if skip_missing is False:
|
||||
self.fail("Error while reading from Swarm manager: %s" % to_native(exc))
|
||||
else:
|
||||
return None
|
||||
self.fail("Error inspecting swarm service: %s" % exc)
|
||||
except Exception as exc:
|
||||
self.fail("Error inspecting swarm service: %s" % exc)
|
||||
|
||||
|
||||
@ -136,7 +136,7 @@ class KubernetesAnsibleScaleModule(KubernetesRawModule):
|
||||
return_obj = self._read_stream(resource, w, stream, name, replicas)
|
||||
|
||||
if not return_obj:
|
||||
return_obj = self._wait_for_response(name, namespace)
|
||||
return_obj = self._wait_for_response(resource, name, namespace)
|
||||
|
||||
return return_obj
|
||||
|
||||
|
||||
@ -129,10 +129,10 @@ def get_config(module, flags=None):
|
||||
return cfg
|
||||
|
||||
|
||||
def run_commands(module, commands, check_rc=True, return_timestamps=False):
|
||||
def run_commands(module, commands, check_rc=True):
|
||||
connection = get_connection(module)
|
||||
try:
|
||||
return connection.run_commands(commands=commands, check_rc=check_rc, return_timestamps=return_timestamps)
|
||||
return connection.run_commands(commands=commands, check_rc=check_rc)
|
||||
except ConnectionError as exc:
|
||||
module.fail_json(msg=to_text(exc))
|
||||
|
||||
|
||||
@ -477,10 +477,10 @@ def load_config(module, command_filter, commit=False, replace=False,
|
||||
return diff
|
||||
|
||||
|
||||
def run_commands(module, commands, check_rc=True, return_timestamps=False):
|
||||
def run_commands(module, commands, check_rc=True):
|
||||
connection = get_connection(module)
|
||||
try:
|
||||
return connection.run_commands(commands=commands, check_rc=check_rc, return_timestamps=return_timestamps)
|
||||
return connection.run_commands(commands=commands, check_rc=check_rc)
|
||||
except ConnectionError as exc:
|
||||
module.fail_json(msg=to_text(exc))
|
||||
|
||||
|
||||
@ -33,7 +33,7 @@ import json
|
||||
import re
|
||||
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.basic import env_fallback, get_timestamp
|
||||
from ansible.module_utils.basic import env_fallback
|
||||
from ansible.module_utils.network.common.utils import to_list, ComplexList
|
||||
from ansible.module_utils.connection import Connection, ConnectionError
|
||||
from ansible.module_utils.common._collections_compat import Mapping
|
||||
@ -154,13 +154,13 @@ class Cli:
|
||||
self._device_configs[cmd] = cfg
|
||||
return cfg
|
||||
|
||||
def run_commands(self, commands, check_rc=True, return_timestamps=False):
|
||||
def run_commands(self, commands, check_rc=True):
|
||||
"""Run list of commands on remote device and return results
|
||||
"""
|
||||
connection = self._get_connection()
|
||||
|
||||
try:
|
||||
out, timestamps = connection.run_commands(commands, check_rc)
|
||||
out = connection.run_commands(commands, check_rc)
|
||||
if check_rc == 'retry_json':
|
||||
capabilities = self.get_capabilities()
|
||||
network_api = capabilities.get('network_api')
|
||||
@ -170,11 +170,8 @@ class Cli:
|
||||
if ('Invalid command at' in resp or 'Ambiguous command at' in resp) and 'json' in resp:
|
||||
if commands[index]['output'] == 'json':
|
||||
commands[index]['output'] = 'text'
|
||||
out, timestamps = connection.run_commands(commands, check_rc)
|
||||
if return_timestamps:
|
||||
return out, timestamps
|
||||
else:
|
||||
return out
|
||||
out = connection.run_commands(commands, check_rc)
|
||||
return out
|
||||
except ConnectionError as exc:
|
||||
self._module.fail_json(msg=to_text(exc))
|
||||
|
||||
@ -344,7 +341,6 @@ class LocalNxapi:
|
||||
|
||||
headers = {'Content-Type': 'application/json'}
|
||||
result = list()
|
||||
timestamps = list()
|
||||
timeout = self._module.params['timeout']
|
||||
use_proxy = self._module.params['provider']['use_proxy']
|
||||
|
||||
@ -352,7 +348,6 @@ class LocalNxapi:
|
||||
if self._nxapi_auth:
|
||||
headers['Cookie'] = self._nxapi_auth
|
||||
|
||||
timestamp = get_timestamp()
|
||||
response, headers = fetch_url(
|
||||
self._module, self._url, data=req, headers=headers,
|
||||
timeout=timeout, method='POST', use_proxy=use_proxy
|
||||
@ -380,13 +375,12 @@ class LocalNxapi:
|
||||
self._error(output=output, **item)
|
||||
elif 'body' in item:
|
||||
result.append(item['body'])
|
||||
timestamps.append(timestamp)
|
||||
# else:
|
||||
# error in command but since check_status is disabled
|
||||
# silently drop it.
|
||||
# result.append(item['msg'])
|
||||
|
||||
return result, timestamps
|
||||
return result
|
||||
|
||||
def get_config(self, flags=None):
|
||||
"""Retrieves the current config from the device or cache
|
||||
@ -400,18 +394,17 @@ class LocalNxapi:
|
||||
try:
|
||||
return self._device_configs[cmd]
|
||||
except KeyError:
|
||||
out, out_timestamps = self.send_request(cmd)
|
||||
out = self.send_request(cmd)
|
||||
cfg = str(out[0]).strip()
|
||||
self._device_configs[cmd] = cfg
|
||||
return cfg
|
||||
|
||||
def run_commands(self, commands, check_rc=True, return_timestamps=False):
|
||||
def run_commands(self, commands, check_rc=True):
|
||||
"""Run list of commands on remote device and return results
|
||||
"""
|
||||
output = None
|
||||
queue = list()
|
||||
responses = list()
|
||||
timestamps = list()
|
||||
|
||||
def _send(commands, output):
|
||||
return self.send_request(commands, output, check_status=check_rc)
|
||||
@ -422,23 +415,16 @@ class LocalNxapi:
|
||||
item['output'] = 'json'
|
||||
|
||||
if all((output == 'json', item['output'] == 'text')) or all((output == 'text', item['output'] == 'json')):
|
||||
out, out_timestamps = _send(queue, output)
|
||||
responses.extend(out)
|
||||
timestamps.extend(out_timestamps)
|
||||
responses.extend(_send(queue, output))
|
||||
queue = list()
|
||||
|
||||
output = item['output'] or 'json'
|
||||
queue.append(item['command'])
|
||||
|
||||
if queue:
|
||||
out, out_timestamps = _send(queue, output)
|
||||
responses.extend(out)
|
||||
timestamps.extend(out_timestamps)
|
||||
responses.extend(_send(queue, output))
|
||||
|
||||
if return_timestamps:
|
||||
return responses, timestamps
|
||||
else:
|
||||
return responses
|
||||
return responses
|
||||
|
||||
def load_config(self, commands, return_error=False, opts=None, replace=None):
|
||||
"""Sends the ordered set of commands to the device
|
||||
@ -450,8 +436,8 @@ class LocalNxapi:
|
||||
commands = 'config replace {0}'.format(replace)
|
||||
|
||||
commands = to_list(commands)
|
||||
msg, msg_timestamps = self.send_request(commands, output='config', check_status=True,
|
||||
return_error=return_error, opts=opts)
|
||||
msg = self.send_request(commands, output='config', check_status=True,
|
||||
return_error=return_error, opts=opts)
|
||||
if return_error:
|
||||
return msg
|
||||
else:
|
||||
@ -530,7 +516,7 @@ class HttpApi:
|
||||
|
||||
return self._connection_obj
|
||||
|
||||
def run_commands(self, commands, check_rc=True, return_timestamps=False):
|
||||
def run_commands(self, commands, check_rc=True):
|
||||
"""Runs list of commands on remote device and returns results
|
||||
"""
|
||||
try:
|
||||
@ -548,11 +534,7 @@ class HttpApi:
|
||||
if response[0] == '{':
|
||||
out[index] = json.loads(response)
|
||||
|
||||
if return_timestamps:
|
||||
# workaround until timestamps are implemented
|
||||
return out, list()
|
||||
else:
|
||||
return out
|
||||
return out
|
||||
|
||||
def get_config(self, flags=None):
|
||||
"""Retrieves the current config from the device or cache
|
||||
@ -726,9 +708,9 @@ def get_config(module, flags=None):
|
||||
return conn.get_config(flags=flags)
|
||||
|
||||
|
||||
def run_commands(module, commands, check_rc=True, return_timestamps=False):
|
||||
def run_commands(module, commands, check_rc=True):
|
||||
conn = get_connection(module)
|
||||
return conn.run_commands(to_command(module, commands), check_rc, return_timestamps)
|
||||
return conn.run_commands(to_command(module, commands), check_rc)
|
||||
|
||||
|
||||
def load_config(module, config, return_error=False, opts=None, replace=None):
|
||||
|
||||
@ -10,7 +10,12 @@ from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.six.moves import http_client
|
||||
from ansible.module_utils.six.moves.urllib.error import URLError, HTTPError
|
||||
|
||||
HEADERS = {'content-type': 'application/json'}
|
||||
GET_HEADERS = {'accept': 'application/json', 'OData-Version': '4.0'}
|
||||
POST_HEADERS = {'content-type': 'application/json', 'accept': 'application/json',
|
||||
'OData-Version': '4.0'}
|
||||
PATCH_HEADERS = {'content-type': 'application/json', 'accept': 'application/json',
|
||||
'OData-Version': '4.0'}
|
||||
DELETE_HEADERS = {'accept': 'application/json', 'OData-Version': '4.0'}
|
||||
|
||||
|
||||
class RedfishUtils(object):
|
||||
@ -25,7 +30,7 @@ class RedfishUtils(object):
|
||||
# The following functions are to send GET/POST/PATCH/DELETE requests
|
||||
def get_request(self, uri):
|
||||
try:
|
||||
resp = open_url(uri, method="GET",
|
||||
resp = open_url(uri, method="GET", headers=GET_HEADERS,
|
||||
url_username=self.creds['user'],
|
||||
url_password=self.creds['pswd'],
|
||||
force_basic_auth=True, validate_certs=False,
|
||||
@ -46,10 +51,10 @@ class RedfishUtils(object):
|
||||
'msg': "Failed GET request to '%s': '%s'" % (uri, to_text(e))}
|
||||
return {'ret': True, 'data': data}
|
||||
|
||||
def post_request(self, uri, pyld, hdrs):
|
||||
def post_request(self, uri, pyld):
|
||||
try:
|
||||
resp = open_url(uri, data=json.dumps(pyld),
|
||||
headers=hdrs, method="POST",
|
||||
headers=POST_HEADERS, method="POST",
|
||||
url_username=self.creds['user'],
|
||||
url_password=self.creds['pswd'],
|
||||
force_basic_auth=True, validate_certs=False,
|
||||
@ -69,10 +74,10 @@ class RedfishUtils(object):
|
||||
'msg': "Failed POST request to '%s': '%s'" % (uri, to_text(e))}
|
||||
return {'ret': True, 'resp': resp}
|
||||
|
||||
def patch_request(self, uri, pyld, hdrs):
|
||||
def patch_request(self, uri, pyld):
|
||||
try:
|
||||
resp = open_url(uri, data=json.dumps(pyld),
|
||||
headers=hdrs, method="PATCH",
|
||||
headers=PATCH_HEADERS, method="PATCH",
|
||||
url_username=self.creds['user'],
|
||||
url_password=self.creds['pswd'],
|
||||
force_basic_auth=True, validate_certs=False,
|
||||
@ -92,10 +97,10 @@ class RedfishUtils(object):
|
||||
'msg': "Failed PATCH request to '%s': '%s'" % (uri, to_text(e))}
|
||||
return {'ret': True, 'resp': resp}
|
||||
|
||||
def delete_request(self, uri, pyld, hdrs):
|
||||
def delete_request(self, uri, pyld):
|
||||
try:
|
||||
resp = open_url(uri, data=json.dumps(pyld),
|
||||
headers=hdrs, method="DELETE",
|
||||
headers=DELETE_HEADERS, method="DELETE",
|
||||
url_username=self.creds['user'],
|
||||
url_password=self.creds['pswd'],
|
||||
force_basic_auth=True, validate_certs=False,
|
||||
@ -302,7 +307,7 @@ class RedfishUtils(object):
|
||||
# Check to make sure option is available, otherwise error is ugly
|
||||
if "Actions" in _data:
|
||||
if "#LogService.ClearLog" in _data[u"Actions"]:
|
||||
self.post_request(self.root_uri + _data[u"Actions"]["#LogService.ClearLog"]["target"], {}, HEADERS)
|
||||
self.post_request(self.root_uri + _data[u"Actions"]["#LogService.ClearLog"]["target"], {})
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
return {'ret': True}
|
||||
@ -468,7 +473,7 @@ class RedfishUtils(object):
|
||||
action_uri = data[key]["#Manager.Reset"]["target"]
|
||||
|
||||
payload = {'ResetType': 'GracefulRestart'}
|
||||
response = self.post_request(self.root_uri + action_uri, payload, HEADERS)
|
||||
response = self.post_request(self.root_uri + action_uri, payload)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
return {'ret': True}
|
||||
@ -491,7 +496,7 @@ class RedfishUtils(object):
|
||||
|
||||
if command in payloads.keys():
|
||||
payload = {'IndicatorLED': payloads[command]}
|
||||
response = self.patch_request(self.root_uri + chassis_uri, payload, HEADERS)
|
||||
response = self.patch_request(self.root_uri + chassis_uri, payload)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
else:
|
||||
@ -534,7 +539,7 @@ class RedfishUtils(object):
|
||||
else:
|
||||
return {'ret': False, 'msg': 'Invalid Command'}
|
||||
|
||||
response = self.post_request(self.root_uri + action_uri, payload, HEADERS)
|
||||
response = self.post_request(self.root_uri + action_uri, payload)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
result['ret'] = True
|
||||
@ -580,7 +585,7 @@ class RedfishUtils(object):
|
||||
roleid = {'RoleId': user['userrole']}
|
||||
enabled = {'Enabled': True}
|
||||
for payload in username, pswd, roleid, enabled:
|
||||
response = self.patch_request(uri, payload, HEADERS)
|
||||
response = self.patch_request(uri, payload)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
return {'ret': True}
|
||||
@ -588,7 +593,7 @@ class RedfishUtils(object):
|
||||
def enable_user(self, user):
|
||||
uri = self.root_uri + self.accounts_uri + "/" + user['userid']
|
||||
payload = {'Enabled': True}
|
||||
response = self.patch_request(uri, payload, HEADERS)
|
||||
response = self.patch_request(uri, payload)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
return {'ret': True}
|
||||
@ -596,7 +601,7 @@ class RedfishUtils(object):
|
||||
def delete_user(self, user):
|
||||
uri = self.root_uri + self.accounts_uri + "/" + user['userid']
|
||||
payload = {'UserName': ""}
|
||||
response = self.patch_request(uri, payload, HEADERS)
|
||||
response = self.patch_request(uri, payload)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
return {'ret': True}
|
||||
@ -604,7 +609,7 @@ class RedfishUtils(object):
|
||||
def disable_user(self, user):
|
||||
uri = self.root_uri + self.accounts_uri + "/" + user['userid']
|
||||
payload = {'Enabled': False}
|
||||
response = self.patch_request(uri, payload, HEADERS)
|
||||
response = self.patch_request(uri, payload)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
return {'ret': True}
|
||||
@ -612,7 +617,7 @@ class RedfishUtils(object):
|
||||
def update_user_role(self, user):
|
||||
uri = self.root_uri + self.accounts_uri + "/" + user['userid']
|
||||
payload = {'RoleId': user['userrole']}
|
||||
response = self.patch_request(uri, payload, HEADERS)
|
||||
response = self.patch_request(uri, payload)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
return {'ret': True}
|
||||
@ -620,7 +625,7 @@ class RedfishUtils(object):
|
||||
def update_user_password(self, user):
|
||||
uri = self.root_uri + self.accounts_uri + "/" + user['userid']
|
||||
payload = {'Password': user['userpswd']}
|
||||
response = self.patch_request(uri, payload, HEADERS)
|
||||
response = self.patch_request(uri, payload)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
return {'ret': True}
|
||||
@ -778,7 +783,7 @@ class RedfishUtils(object):
|
||||
data = response['data']
|
||||
reset_bios_settings_uri = data["Actions"]["#Bios.ResetBios"]["target"]
|
||||
|
||||
response = self.post_request(self.root_uri + reset_bios_settings_uri, {}, HEADERS)
|
||||
response = self.post_request(self.root_uri + reset_bios_settings_uri, {})
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
return {'ret': True, 'changed': True, 'msg': "Set BIOS to default settings"}
|
||||
@ -810,7 +815,7 @@ class RedfishUtils(object):
|
||||
else:
|
||||
payload = {"Boot": {"BootSourceOverrideTarget": bootdevice}}
|
||||
|
||||
response = self.patch_request(self.root_uri + self.systems_uris[0], payload, HEADERS)
|
||||
response = self.patch_request(self.root_uri + self.systems_uris[0], payload)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
return {'ret': True}
|
||||
@ -851,7 +856,7 @@ class RedfishUtils(object):
|
||||
# Example: bios_attr = {\"name\":\"value\"}
|
||||
bios_attr = "{\"" + attr['bios_attr_name'] + "\":\"" + attr['bios_attr_value'] + "\"}"
|
||||
payload = {"Attributes": json.loads(bios_attr)}
|
||||
response = self.patch_request(self.root_uri + set_bios_attr_uri, payload, HEADERS)
|
||||
response = self.patch_request(self.root_uri + set_bios_attr_uri, payload)
|
||||
if response['ret'] is False:
|
||||
return response
|
||||
return {'ret': True, 'changed': True, 'msg': "Modified BIOS attribute"}
|
||||
|
||||
@ -514,10 +514,11 @@ def connect_to_api(module, disconnect_atexit=True):
|
||||
module.fail_json(msg='pyVim does not support changing verification mode with python < 2.7.9. Either update '
|
||||
'python or use validate_certs=false.')
|
||||
|
||||
ssl_context = None
|
||||
if not validate_certs and hasattr(ssl, 'SSLContext'):
|
||||
ssl_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
|
||||
ssl_context.verify_mode = ssl.CERT_NONE
|
||||
ssl_context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
|
||||
if validate_certs:
|
||||
ssl_context.verify_mode = ssl.CERT_REQUIRED
|
||||
ssl_context.check_hostname = True
|
||||
ssl_context.load_default_certs()
|
||||
|
||||
service_instance = None
|
||||
try:
|
||||
@ -1109,7 +1110,7 @@ class PyVmomi(object):
|
||||
for host in esxi_host_name:
|
||||
esxi_host_obj = self.find_hostsystem_by_name(host_name=host)
|
||||
if esxi_host_obj:
|
||||
host_obj_list = [esxi_host_obj]
|
||||
host_obj_list.append(esxi_host_obj)
|
||||
else:
|
||||
self.module.fail_json(changed=False, msg="ESXi '%s' not found" % host)
|
||||
|
||||
|
||||
@ -128,15 +128,15 @@ class Vultr:
|
||||
return
|
||||
|
||||
r_value = resource.get(resource_key)
|
||||
if isinstance(param, bool):
|
||||
if param is True and r_value not in ['yes', 'enable']:
|
||||
if r_value in ['yes', 'no']:
|
||||
if param and r_value != 'yes':
|
||||
return "enable"
|
||||
elif param is False and r_value not in ['no', 'disable']:
|
||||
elif not param and r_value != 'no':
|
||||
return "disable"
|
||||
else:
|
||||
if r_value is None:
|
||||
if param and not r_value:
|
||||
return "enable"
|
||||
else:
|
||||
elif not param and r_value:
|
||||
return "disable"
|
||||
|
||||
def api_query(self, path="/", method="GET", data=None):
|
||||
|
||||
@ -431,7 +431,6 @@ EXAMPLES = '''
|
||||
|
||||
- name: Terminate instances
|
||||
hosts: localhost
|
||||
connection: local
|
||||
tasks:
|
||||
- name: Terminate instances that were previously launched
|
||||
ec2:
|
||||
@ -444,7 +443,6 @@ EXAMPLES = '''
|
||||
- name: Start sandbox instances
|
||||
hosts: localhost
|
||||
gather_facts: false
|
||||
connection: local
|
||||
vars:
|
||||
instance_ids:
|
||||
- 'i-xxxxxx'
|
||||
@ -467,7 +465,6 @@ EXAMPLES = '''
|
||||
- name: Stop sandbox instances
|
||||
hosts: localhost
|
||||
gather_facts: false
|
||||
connection: local
|
||||
vars:
|
||||
instance_ids:
|
||||
- 'i-xxxxxx'
|
||||
|
||||
@ -229,6 +229,7 @@ EXAMPLES = '''
|
||||
|
||||
- name: "Delete group by its id"
|
||||
ec2_group:
|
||||
region: eu-west-1
|
||||
group_id: sg-33b4ee5b
|
||||
state: absent
|
||||
'''
|
||||
|
||||
@ -73,7 +73,7 @@ options:
|
||||
ebs:
|
||||
description: Parameters used to automatically set up EBS volumes when the instance is launched.
|
||||
suboptions:
|
||||
delete_on_termintation:
|
||||
delete_on_termination:
|
||||
description: Indicates whether the EBS volume is deleted on instance termination.
|
||||
type: bool
|
||||
encrypted:
|
||||
|
||||
@ -35,12 +35,16 @@ options:
|
||||
type: bool
|
||||
access_logs_s3_bucket:
|
||||
description:
|
||||
- The name of the S3 bucket for the access logs. This attribute is required if access logs in Amazon S3 are enabled. The bucket must exist in the same
|
||||
- The name of the S3 bucket for the access logs.
|
||||
- Required if access logs in Amazon S3 are enabled.
|
||||
- The bucket must exist in the same
|
||||
region as the load balancer and have a bucket policy that grants Elastic Load Balancing permission to write to the bucket.
|
||||
required: false
|
||||
access_logs_s3_prefix:
|
||||
description:
|
||||
- The prefix for the location in the S3 bucket. If you don't specify a prefix, the access logs are stored in the root of the bucket.
|
||||
- The prefix for the log location in the S3 bucket.
|
||||
- If you don't specify a prefix, the access logs are stored in the root of the bucket.
|
||||
- Cannot begin or end with a slash.
|
||||
required: false
|
||||
deletion_protection:
|
||||
description:
|
||||
@ -161,7 +165,7 @@ EXAMPLES = '''
|
||||
- elb_application_lb:
|
||||
access_logs_enabled: yes
|
||||
access_logs_s3_bucket: mybucket
|
||||
access_logs_s3_prefix: "/logs"
|
||||
access_logs_s3_prefix: "logs"
|
||||
name: myelb
|
||||
security_groups:
|
||||
- sg-12345678
|
||||
@ -232,7 +236,7 @@ access_logs_s3_prefix:
|
||||
description: The prefix for the location in the S3 bucket.
|
||||
returned: when state is present
|
||||
type: str
|
||||
sample: /my/logs
|
||||
sample: my/logs
|
||||
availability_zones:
|
||||
description: The Availability Zones for the load balancer.
|
||||
returned: when state is present
|
||||
|
||||
@ -1050,7 +1050,7 @@ def main():
|
||||
new_db_instance_identifier=dict(aliases=['new_instance_id', 'new_id']),
|
||||
option_group_name=dict(),
|
||||
performance_insights_kms_key_id=dict(),
|
||||
performance_insights_retention_period=dict(),
|
||||
performance_insights_retention_period=dict(type='int'),
|
||||
port=dict(type='int'),
|
||||
preferred_backup_window=dict(aliases=['backup_window']),
|
||||
preferred_maintenance_window=dict(aliases=['maintenance_window']),
|
||||
|
||||
@ -365,6 +365,8 @@ class AzureRMFunctionApp(AzureRMModuleBase):
|
||||
function_app_settings.append(NameValuePair(name='WEBSITE_CONTENTSHARE', value=self.name))
|
||||
else:
|
||||
function_app_settings.append(NameValuePair(name='FUNCTIONS_EXTENSION_VERSION', value='~2'))
|
||||
function_app_settings.append(NameValuePair(name='WEBSITES_ENABLE_APP_SERVICE_STORAGE', value=False))
|
||||
function_app_settings.append(NameValuePair(name='AzureWebJobsStorage', value=self.storage_connection_string))
|
||||
|
||||
return function_app_settings
|
||||
|
||||
|
||||
@ -138,7 +138,8 @@ def managed_disk_to_dict(managed_disk):
|
||||
disk_size_gb=managed_disk.disk_size_gb,
|
||||
os_type=managed_disk.os_type.lower() if managed_disk.os_type else None,
|
||||
storage_account_type=managed_disk.sku.name if managed_disk.sku else None,
|
||||
managed_by=managed_disk.managed_by
|
||||
managed_by=managed_disk.managed_by,
|
||||
zone=managed_disk.zones[0] if managed_disk.zones and len(managed_disk.zones) > 0 else ''
|
||||
)
|
||||
|
||||
|
||||
|
||||
@ -145,7 +145,8 @@ class AzureRMResourceGroupFacts(AzureRMModuleBase):
|
||||
|
||||
self.results = dict(
|
||||
changed=False,
|
||||
ansible_facts=dict(azure_resourcegroups=[])
|
||||
ansible_facts=dict(azure_resourcegroups=[]),
|
||||
resourcegroups=[]
|
||||
)
|
||||
|
||||
self.name = None
|
||||
@ -170,6 +171,8 @@ class AzureRMResourceGroupFacts(AzureRMModuleBase):
|
||||
for item in self.results['ansible_facts']['azure_resourcegroups']:
|
||||
item['resources'] = self.list_by_rg(item['name'])
|
||||
|
||||
self.results['resourcegroups'] = self.results['ansible_facts']['azure_resourcegroups']
|
||||
|
||||
return self.results
|
||||
|
||||
def get_item(self):
|
||||
|
||||
@ -84,7 +84,6 @@ options:
|
||||
|
||||
extends_documentation_fragment:
|
||||
- azure
|
||||
- azure_tags
|
||||
|
||||
author:
|
||||
- "Chris Houseknecht (@chouseknecht)"
|
||||
@ -219,7 +218,8 @@ class AzureRMSubnet(AzureRMModuleBase):
|
||||
self.service_endpoints = None
|
||||
|
||||
super(AzureRMSubnet, self).__init__(self.module_arg_spec,
|
||||
supports_check_mode=True)
|
||||
supports_check_mode=True,
|
||||
supports_tags=False)
|
||||
|
||||
def exec_module(self, **kwargs):
|
||||
|
||||
|
||||
@ -839,9 +839,15 @@ class AzureRMVirtualMachineScaleSet(AzureRMModuleBase):
|
||||
.ip_configurations[0].load_balancer_backend_address_pools = load_balancer_backend_address_pools
|
||||
vmss_resource.virtual_machine_profile.network_profile.network_interface_configurations[0] \
|
||||
.ip_configurations[0].load_balancer_inbound_nat_pools = load_balancer_inbound_nat_pools
|
||||
vmss_resource.virtual_machine_profile.network_profile.network_interface_configurations[0] \
|
||||
.ip_configurations[0].application_gateway_backend_address_pools = None
|
||||
elif self.application_gateway:
|
||||
vmss_resource.virtual_machine_profile.network_profile.network_interface_configurations[0] \
|
||||
.ip_configurations[0].application_gateway_backend_address_pools = application_gateway_backend_address_pools
|
||||
vmss_resource.virtual_machine_profile.network_profile.network_interface_configurations[0] \
|
||||
.ip_configurations[0].load_balancer_backend_address_pools = None
|
||||
vmss_resource.virtual_machine_profile.network_profile.network_interface_configurations[0] \
|
||||
.ip_configurations[0].load_balancer_inbound_nat_pools = None
|
||||
|
||||
if self.data_disks is not None:
|
||||
data_disks = []
|
||||
|
||||
@ -165,7 +165,6 @@ EXAMPLES = '''
|
||||
|
||||
- name: Run using a project directory
|
||||
hosts: localhost
|
||||
connection: local
|
||||
gather_facts: no
|
||||
tasks:
|
||||
- docker_compose:
|
||||
@ -220,7 +219,6 @@ EXAMPLES = '''
|
||||
|
||||
- name: Scale the web service to 2
|
||||
hosts: localhost
|
||||
connection: local
|
||||
gather_facts: no
|
||||
tasks:
|
||||
- docker_compose:
|
||||
@ -234,7 +232,6 @@ EXAMPLES = '''
|
||||
|
||||
- name: Run with inline v2 compose
|
||||
hosts: localhost
|
||||
connection: local
|
||||
gather_facts: no
|
||||
tasks:
|
||||
- docker_compose:
|
||||
@ -269,7 +266,6 @@ EXAMPLES = '''
|
||||
|
||||
- name: Run with inline v1 compose
|
||||
hosts: localhost
|
||||
connection: local
|
||||
gather_facts: no
|
||||
tasks:
|
||||
- docker_compose:
|
||||
|
||||
@ -85,7 +85,7 @@ EXAMPLES = '''
|
||||
# If the file is JSON or binary, Ansible might modify it (because
|
||||
# it is first decoded and later re-encoded). Base64-encoding the
|
||||
# file directly after reading it prevents this to happen.
|
||||
data: "{{ lookup('file', '/path/to/config/file') | base64 }}"
|
||||
data: "{{ lookup('file', '/path/to/config/file') | b64encode }}"
|
||||
data_is_b64: true
|
||||
state: present
|
||||
|
||||
|
||||
@ -486,7 +486,6 @@ options:
|
||||
- "Bind addresses must be either IPv4 or IPv6 addresses. Hostnames are I(not) allowed. This
|
||||
is different from the C(docker) command line utility. Use the L(dig lookup,../lookup/dig.html)
|
||||
to resolve hostnames."
|
||||
- Container ports must be exposed either in the Dockerfile or via the C(expose) option.
|
||||
- A value of C(all) will publish all exposed container ports to random host ports, ignoring
|
||||
any other mappings.
|
||||
- If C(networks) parameter is provided, will inspect each network to see if there exists
|
||||
@ -1586,7 +1585,14 @@ class TaskParameters(DockerBaseClass):
|
||||
if self.log_options is not None:
|
||||
options['Config'] = dict()
|
||||
for k, v in self.log_options.items():
|
||||
options['Config'][k] = str(v)
|
||||
if not isinstance(v, string_types):
|
||||
self.client.module.warn(
|
||||
"Non-string value found for log_options option '%s'. The value is automatically converted to '%s'. "
|
||||
"If this is not correct, or you want to avoid such warnings, please quote the value." % (k, str(v))
|
||||
)
|
||||
v = str(v)
|
||||
self.log_options[k] = v
|
||||
options['Config'][k] = v
|
||||
|
||||
try:
|
||||
return LogConfig(**options)
|
||||
@ -1622,8 +1628,8 @@ class TaskParameters(DockerBaseClass):
|
||||
if self.env:
|
||||
for name, value in self.env.items():
|
||||
if not isinstance(value, string_types):
|
||||
self.fail("Non-string value found for env option. "
|
||||
"Ambiguous env options must be wrapped in quotes to avoid YAML parsing. Key: %s" % (name, ))
|
||||
self.fail("Non-string value found for env option. Ambiguous env options must be "
|
||||
"wrapped in quotes to avoid them being interpreted. Key: %s" % (name, ))
|
||||
final_env[name] = str(value)
|
||||
return final_env
|
||||
|
||||
@ -2761,8 +2767,8 @@ class AnsibleDockerClientContainer(AnsibleDockerClient):
|
||||
key_main = comp_aliases.get(key)
|
||||
if key_main is None:
|
||||
if key_main in all_options:
|
||||
self.fail(("The module option '%s' cannot be specified in the comparisons dict," +
|
||||
" since it does not correspond to container's state!") % key)
|
||||
self.fail("The module option '%s' cannot be specified in the comparisons dict, "
|
||||
"since it does not correspond to container's state!" % key)
|
||||
self.fail("Unknown module option '%s' in comparisons dict!" % key)
|
||||
if key_main in comp_aliases_used:
|
||||
self.fail("Both '%s' and '%s' (aliases of %s) are specified in comparisons dict!" % (key, comp_aliases_used[key_main], key_main))
|
||||
|
||||
@ -245,15 +245,18 @@ class DockerHostManager(DockerBaseClass):
|
||||
header_images = ['Id', 'RepoTags', 'Created', 'Size']
|
||||
header_networks = ['Id', 'Driver', 'Name', 'Scope']
|
||||
|
||||
filter_arg = dict()
|
||||
if filters:
|
||||
filter_arg['filters'] = filters
|
||||
try:
|
||||
if docker_object == 'containers':
|
||||
items = self.client.containers(filters=filters)
|
||||
items = self.client.containers(**filter_arg)
|
||||
elif docker_object == 'networks':
|
||||
items = self.client.networks(filters=filters)
|
||||
items = self.client.networks(**filter_arg)
|
||||
elif docker_object == 'images':
|
||||
items = self.client.images(filters=filters)
|
||||
items = self.client.images(**filter_arg)
|
||||
elif docker_object == 'volumes':
|
||||
items = self.client.volumes(filters=filters)
|
||||
items = self.client.volumes(**filter_arg)
|
||||
except APIError as exc:
|
||||
self.client.fail("Error inspecting docker host for object '%s': %s" %
|
||||
(docker_object, to_native(exc)))
|
||||
@ -301,11 +304,17 @@ def main():
|
||||
verbose_output=dict(type='bool', default=False),
|
||||
)
|
||||
|
||||
option_minimal_versions = dict(
|
||||
network_filters=dict(docker_py_version='2.0.2'),
|
||||
disk_usage=dict(docker_py_version='2.2.0'),
|
||||
)
|
||||
|
||||
client = AnsibleDockerClient(
|
||||
argument_spec=argument_spec,
|
||||
supports_check_mode=True,
|
||||
min_docker_version='1.10.0',
|
||||
min_docker_api_version='1.21',
|
||||
option_minimal_versions=option_minimal_versions,
|
||||
fail_results=dict(
|
||||
can_talk_to_docker=False,
|
||||
),
|
||||
|
||||
@ -85,7 +85,7 @@ EXAMPLES = '''
|
||||
# If the file is JSON or binary, Ansible might modify it (because
|
||||
# it is first decoded and later re-encoded). Base64-encoding the
|
||||
# file directly after reading it prevents this to happen.
|
||||
data: "{{ lookup('file', '/path/to/secret/file') | base64 }}"
|
||||
data: "{{ lookup('file', '/path/to/secret/file') | b64encode }}"
|
||||
data_is_b64: true
|
||||
state: present
|
||||
|
||||
|
||||
@ -58,15 +58,15 @@ options:
|
||||
uid:
|
||||
description:
|
||||
- UID of the config file's owner.
|
||||
type: int
|
||||
type: str
|
||||
gid:
|
||||
description:
|
||||
- GID of the config file's group.
|
||||
type: int
|
||||
type: str
|
||||
mode:
|
||||
description:
|
||||
- File access mode inside the container.
|
||||
type: str
|
||||
- File access mode inside the container. Must be an octal number (like C(0644) or C(0444)).
|
||||
type: int
|
||||
constraints:
|
||||
description:
|
||||
- List of the service constraints.
|
||||
@ -611,14 +611,14 @@ options:
|
||||
uid:
|
||||
description:
|
||||
- UID of the secret file's owner.
|
||||
type: int
|
||||
type: str
|
||||
gid:
|
||||
description:
|
||||
- GID of the secret file's group.
|
||||
type: int
|
||||
type: str
|
||||
mode:
|
||||
description:
|
||||
- File access mode inside the container.
|
||||
- File access mode inside the container. Must be an octal number (like C(0644) or C(0444)).
|
||||
type: int
|
||||
state:
|
||||
description:
|
||||
@ -2250,8 +2250,8 @@ class DockerServiceManager(object):
|
||||
'config_id': config_data['ConfigID'],
|
||||
'config_name': config_data['ConfigName'],
|
||||
'filename': config_data['File'].get('Name'),
|
||||
'uid': int(config_data['File'].get('UID')),
|
||||
'gid': int(config_data['File'].get('GID')),
|
||||
'uid': config_data['File'].get('UID'),
|
||||
'gid': config_data['File'].get('GID'),
|
||||
'mode': config_data['File'].get('Mode')
|
||||
})
|
||||
|
||||
@ -2263,8 +2263,8 @@ class DockerServiceManager(object):
|
||||
'secret_id': secret_data['SecretID'],
|
||||
'secret_name': secret_data['SecretName'],
|
||||
'filename': secret_data['File'].get('Name'),
|
||||
'uid': int(secret_data['File'].get('UID')),
|
||||
'gid': int(secret_data['File'].get('GID')),
|
||||
'uid': secret_data['File'].get('UID'),
|
||||
'gid': secret_data['File'].get('GID'),
|
||||
'mode': secret_data['File'].get('Mode')
|
||||
})
|
||||
|
||||
@ -2506,16 +2506,16 @@ def main():
|
||||
config_id=dict(type='str', required=True),
|
||||
config_name=dict(type='str', required=True),
|
||||
filename=dict(type='str'),
|
||||
uid=dict(type='int'),
|
||||
gid=dict(type='int'),
|
||||
uid=dict(type='str'),
|
||||
gid=dict(type='str'),
|
||||
mode=dict(type='int'),
|
||||
)),
|
||||
secrets=dict(type='list', elements='dict', options=dict(
|
||||
secret_id=dict(type='str', required=True),
|
||||
secret_name=dict(type='str', required=True),
|
||||
filename=dict(type='str'),
|
||||
uid=dict(type='int'),
|
||||
gid=dict(type='int'),
|
||||
uid=dict(type='str'),
|
||||
gid=dict(type='str'),
|
||||
mode=dict(type='int'),
|
||||
)),
|
||||
networks=dict(type='list', elements='str'),
|
||||
|
||||
@ -13,7 +13,7 @@ __metaclass__ = type
|
||||
################################################################################
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'status': ['deprecated'],
|
||||
'supported_by': 'community'}
|
||||
|
||||
|
||||
@ -28,6 +28,10 @@ author: "William Albert (@walbert947)"
|
||||
requirements:
|
||||
- "python >= 2.6"
|
||||
- "apache-libcloud >= 0.19.0"
|
||||
deprecated:
|
||||
removed_in: "2.12"
|
||||
why: Updated modules released with increased functionality
|
||||
alternative: Use M(gcp_dns_resource_record_set) instead.
|
||||
options:
|
||||
state:
|
||||
description:
|
||||
@ -13,7 +13,7 @@ __metaclass__ = type
|
||||
################################################################################
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'status': ['deprecated'],
|
||||
'supported_by': 'community'}
|
||||
|
||||
|
||||
@ -27,6 +27,10 @@ version_added: "2.2"
|
||||
author: "William Albert (@walbert947)"
|
||||
requirements:
|
||||
- "apache-libcloud >= 0.19.0"
|
||||
deprecated:
|
||||
removed_in: "2.12"
|
||||
why: Updated modules released with increased functionality
|
||||
alternative: Use M(gcp_dns_managed_zone) instead.
|
||||
options:
|
||||
state:
|
||||
description:
|
||||
@ -7,7 +7,7 @@ __metaclass__ = type
|
||||
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'status': ['deprecated'],
|
||||
'supported_by': 'community'}
|
||||
DOCUMENTATION = '''
|
||||
module: gcp_backend_service
|
||||
@ -25,6 +25,10 @@ notes:
|
||||
- Update is not currently supported.
|
||||
- Only global backend services are currently supported. Regional backends not currently supported.
|
||||
- Internal load balancing not currently supported.
|
||||
deprecated:
|
||||
removed_in: "2.12"
|
||||
why: Updated modules released with increased functionality
|
||||
alternative: Use M(gcp_compute_backend_service) instead.
|
||||
author:
|
||||
- "Tom Melendez (@supertom) <tom@supertom.com>"
|
||||
options:
|
||||
@ -7,7 +7,7 @@ __metaclass__ = type
|
||||
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
||||
'status': ['preview'],
|
||||
'status': ['deprecated'],
|
||||
'supported_by': 'community'}
|
||||
|
||||
|
||||
@ -28,6 +28,10 @@ requirements:
|
||||
- "google-api-python-client >= 1.6.2"
|
||||
- "google-auth >= 0.9.0"
|
||||
- "google-auth-httplib2 >= 0.0.2"
|
||||
deprecated:
|
||||
removed_in: "2.12"
|
||||
why: Updated modules released with increased functionality
|
||||
alternative: Use M(gcp_compute_forwarding_rule) or M(gcp_compute_global_forwarding_rule) instead.
|
||||
notes:
|
||||
- Currently only supports global forwarding rules.
|
||||
As such, Load Balancing Scheme is always EXTERNAL.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user